A Discord.NET bot made for the server Unity Developer Community Join us on Discord !
The code is provided as-is and there will be no guaranteed support to help make it run.
| Feature | Description |
|---|---|
| User Profiles | XP/level system, karma tracking, profile cards with customizable skins |
| Moderation | Mute, kick, ban, slowmode, message clearing, audit logging |
| Slash Commands | Modern Discord slash command support alongside text commands |
| Casino | Token economy with Blackjack, Poker, and Rock Paper Scissors (details) |
| Weather | Temperature, conditions, air quality, and local time via OpenWeatherMap |
| Reminders | Persistent scheduled reminders with natural time parsing |
| Tips | Searchable tip database with image support |
| Tickets | Private complaint/support ticket system |
| Unity Help | Help forum thread management, auto-archive, canned responses, FAQ/resources |
| Recruitment | Configurable recruitment workflow |
| Birthday Announcements | Scheduled birthday notifications |
| Currency Conversion | Real-time currency conversion |
| Flight Data | Airport and flight lookups |
| RSS Feeds | Feed parsing and management |
| Leaderboards | XP, karma (weekly/monthly/yearly), and casino token leaderboards |
This bot follows a Service-Module architecture pattern designed for maintainability and separation of concerns.
Services (/DiscordBot/Services/) contain the core business logic and data operations:
- Handle database interactions, API calls, and background tasks
- Maintain state and provide reusable functionality
- Examples:
UserService,DatabaseService,ModerationService,LoggingService - Registered as singletons in the dependency injection container
Modules (/DiscordBot/Modules/) handle Discord command interactions:
- Expose functionality to users via chat commands
- Use
[Command]attributes to define command behavior - Receive services via dependency injection
- Examples:
UserModule,TipModule,ModerationModule
The bot uses .NET's built-in dependency injection system:
- Services are registered in
Program.csusingConfigureServices() - Modules receive services via public property injection
- This allows for loose coupling and easier testing
The bot supports both text commands and slash commands:
Text Commands (via CommandService):
- Use attributes like
[Command("commandname")]and[Summary("description")] - Triggered by the configured prefix (default
!)
Slash Commands (via InteractionService):
- Use
[SlashCommand],[Group], and[ComponentInteraction]attributes - Registered per-guild using
GuildIdfrom settings - Support autocomplete, buttons, modals, and select menus
Shared:
- Custom attributes provide authorization:
[RequireModerator],[RequireAdmin] - Command routing is handled by
CommandHandlingService
- Choose the appropriate module or create a new one in
/DiscordBot/Modules/ - Add the command method with proper attributes:
[Command("mycommand")]
[Summary("Description of what this command does")]
[RequireModerator] // Optional: Add permission requirements
public async Task MyCommand(string parameter)
{
// Your command logic here
await ReplyAsync("Command executed!");
}- Inject required services via public properties:
public UserService UserService { get; set; }
public DatabaseService DatabaseService { get; set; }- Choose an existing interaction module or create a new one in
/DiscordBot/Modules/ - Add the slash command method with proper attributes:
[SlashCommand("mycommand", "Description of what this command does")]
public async Task MyCommand(
[Summary(description: "A parameter")] string parameter)
{
await RespondAsync("Command executed!");
}- For grouped commands, use the
[Group]attribute on the class:
[Group("mygroup", "Group description")]
public class MySlashModule : InteractionModuleBase<SocketInteractionContext>
{
[SlashCommand("subcommand", "Subcommand description")]
public async Task SubCommand() => await RespondAsync("Done!");
}Slash commands are registered per-guild on startup using the
GuildIdsetting.
- Create your service class in
/DiscordBot/Services/:
public class MyNewService
{
private readonly DatabaseService _databaseService;
public MyNewService(DatabaseService databaseService)
{
_databaseService = databaseService;
}
public async Task DoSomethingAsync()
{
// Your service logic here
}
}- Register the service in
Program.cswithinConfigureServices():
.AddSingleton<MyNewService>()- Inject it into modules that need it:
public MyNewService MyNewService { get; set; }Create custom precondition attributes in /DiscordBot/Attributes/:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class RequireMyRoleAttribute : PreconditionAttribute
{
public override Task<PreconditionResult> CheckPermissionsAsync(
ICommandContext context, CommandInfo command, IServiceProvider services)
{
var user = (SocketGuildUser)context.Message.Author;
var settings = services.GetRequiredService<BotSettings>();
if (user.Roles.Any(x => x.Id == settings.MyRoleId))
return Task.FromResult(PreconditionResult.FromSuccess());
return Task.FromResult(PreconditionResult.FromError("Access denied!"));
}
}To successfully compile you will need the following:
Required:
- .NET 8.0 SDK or later
- An IDE such as Visual Studio, VS Code, or JetBrains Rider
Recommended for Development:
- Docker and Docker Compose for database containerization
Build the project:
dotnet restore
dotnet buildNote: Docker is highly recommended for local development as it simplifies database setup and ensures consistency across development environments.
-
Copy required folders:
- Copy the
DiscordBot/SERVERfolder to your build output directory - If unsure of the location, run the bot once - it will show an error with the expected path
- Copy the
-
Configure settings:
- Copy
DiscordBot/Settingsfolder to theSERVERfolder (exclude theDeserializedsubfolder) - Copy
Settings.example.jsonand rename it toSettings.json - Edit
Settings.jsonand configure:- Bot Token: Get this from the Discord Developer Portal
- DbConnectionString: Database connection details (see database setup below)
- Copy
-
Choose your database setup: Docker (recommended) or Manual setup
Important: Read the comments in
Settings.jsoncarefully - they explain which settings need to be changed and which are optional.
For production deployment, see the Deployment Guide.
Recommended for development: Docker simplifies database setup and ensures consistency.
To run with Docker:
# Start both database and bot
docker-compose up
# Start only the database (run bot from IDE for faster development)
docker-compose up dbDevelopment workflow:
- Start the database container:
docker-compose up db - Update the
DbConnectionStringinSettings.jsonto match your docker-compose configuration - Run the bot from your IDE for faster development iteration
Full Docker deployment:
# Build and start everything
docker-compose up --build --remove-orphans
# Run in background
docker-compose up -dTip: For active development, use Docker only for the database and run the bot from your IDE - this gives you faster restart times and better debugging capabilities.
Manual Database Setup (Alternative to Docker):
If you prefer not to use Docker, you'll need to set up a MySQL database manually:
-
Install MySQL server:
- Windows/macOS: XAMPP (includes MySQL + phpMyAdmin)
- Linux:
sudo apt install mysql-serveror equivalent
-
Create database and user:
- Create a new database for the bot
- Create a user with full permissions to that database
- Update the
DbConnectionStringinSettings.jsonwith your database details
-
Initialize database schema:
- The bot will attempt to create necessary tables on first run
- If it fails due to permissions, you may need to run it with elevated database privileges initially
Additional Linux Requirements: For image processing functionality, install Microsoft Core Fonts:
sudo apt install ttf-mscorefonts-installerConnection String Format:
"DbConnectionString": "Server=localhost;Database=your_db_name;Uid=your_username;Pwd=your_password;"The bot includes comprehensive logging to help with troubleshooting:
Log Levels and Colors:
- Critical/Error: Red text - Something is broken and needs immediate attention
- Warning: Yellow text - Potential issues that should be investigated
- Info: White text - General operational information
- Verbose/Debug: Gray text - Detailed information for development
During startup: Any yellow or red messages likely indicate configuration or connectivity issues.
Log Locations:
- Console output for immediate feedback
- Channel logging (if configured) for persistent records
- See LoggingService for implementation details
This bot is built on Discord.Net, a powerful .NET library for Discord bots.
Key Concepts to Understand:
- Asynchronous Programming: Extensive use of
async/awaitpatterns - Event-Driven Architecture: Reactions to Discord events (messages, user joins, etc.)
- Polymorphism: Rich type hierarchy for Discord entities (users, channels, guilds)
Helpful Resources:
- Discord.Net Documentation
- Discord.Net API Reference
- Discord Developer Portal for Discord API specifics
Common Patterns in this Bot:
- Commands return
Taskfor async operations - Heavy use of dependency injection for service access
- Event handlers for background functionality (user joins, message processing)
Q: The bot won't start - what should I check? A: Verify these in order:
- Bot token is correctly set in
Settings.json - Database connection string is correct and database is accessible
- All required folders (SERVER, Settings) are in the right location
- Check console output for red/yellow log messages indicating specific errors
Q: "Unable to load the service index" or NuGet restore errors A: This is usually a temporary network issue with package sources. Try: Warning: Clearing NuGet locals will remove all cached packages and temporary files. This may require re-downloading dependencies, which could take significant time on slower connections.
dotnet nuget locals all --clear
dotnet restoreQ: Database connection fails A: Common causes:
- Incorrect connection string format
- Database server not running
- User permissions insufficient
- Firewall blocking database port
Q: How do I get a Discord bot token? A:
- Go to Discord Developer Portal
- Create a new application
- Go to "Bot" section
- Click "Add Bot" and copy the token
- Invite the bot to your server with appropriate permissions
Q: What permissions does the bot need? A: The bot requires:
- Read Messages
- Send Messages
- Manage Messages (for moderation features)
- Add Reactions
- Use Slash Commands
- Additional permissions based on enabled features
Q: How can I contribute or report bugs? A:
- Check existing issues on GitHub
- For bugs: provide console logs and steps to reproduce
- For contributions: see the Contributing section above
Q: How do I debug commands? A:
- Use the logging system:
LoggingService.LogToConsole(message, ExtendedLogSeverity.Info) - Set breakpoints in your IDE when running the bot locally
- Check the command history in
CommandHandlingService
Q: My command isn't working A: Common issues:
- Missing
[Command]attribute - Incorrect parameter types
- Missing dependency injection setup
- Permission attribute blocking execution