The Discord bot for The Great Outdoors community server. It handles moderation, logging, member onboarding, channel automation, an AI chatbot ("Steve"), and various utility and reference commands.
Built with Sapphire on top of discord.js, written in TypeScript (ESM), and backed by PostgreSQL via Drizzle ORM.
- Node.js (LTS)
- pnpm 10+
- A PostgreSQL database
- A Discord bot application (Developer Portal)
- An OpenAI API key
pnpm installCreate a .env file with the required configuration. Every value is validated at startup by the Zod schema in src/env.ts — see that file for the complete, authoritative list.
Push the database schema:
pnpm db pushpnpm dev # build, then startOr separately:
pnpm build # compile src/ -> dist/
pnpm start # run the compiled botCommands are registered only in the guild set by GUILD_ID, and are bulk-overwritten on every startup.
| Command | Description |
|---|---|
pnpm dev |
Build then start |
pnpm build |
Compile TypeScript to dist/ |
pnpm start |
Run the compiled bot (node .) |
pnpm types |
Typecheck without emitting |
pnpm format |
Format with Prettier |
pnpm format:check |
Check formatting |
pnpm check |
format + types |
pnpm knip |
Report unused code/dependencies |
pnpm db |
Drizzle Kit CLI (e.g. pnpm db push, generate) |
CI runs format:check, types, build, and knip on every push and pull request.
src/
bot.ts Entry point: client config, login, cron init
env.ts Zod-validated environment configuration
commands/ Slash & context commands (fun, moderation, reference, utility)
listeners/ Discord event handlers (autoMod, channels, logging, utilities)
lib/ Business logic (moderation, llm, autoRole, linkCleaner, ...)
jobs/ Scheduled cron jobs
db/ Drizzle schema and client
util/ Small shared helpers
Commands, listeners, and interaction handlers are auto-loaded by Sapphire based on their directory. Discord roles, channels, and forum tags are accessed through the typed helper functions in src/lib/loadDiscordObjects.ts.
Licensed under the GNU Affero General Public License (AGPL). See LICENSE.