⚠️ Currently, this repo serves as documentation. Code will follow eventually :-)
- Clean up code and migrate to slash commands -> Reevaluate current architecture (no need for help cmd?)
- Move to (this) public repo
Discord bot template that makes it possible to run multiple different Discord bots under a single bot in a Docker based microservice architecture managed by Docker Compose. Written in C# using Discord.NET.
To obtain a seperation of concerns, it is tempting to seperate different functionality into multiple different Discord bots in a microservice architecture. This projects acts as a template/library that allows to easely share common implementation, such as messaging, configuration, audio playing, help commands etc., between multiple different bots and at the same time make the bots appear as a single bot in the Discord UI client. As such, only one Discord bot needs to be added to a guild rather than a bot for each microservice.
To summarize, the template bot make it possible to:
- Share common Discord bot functionality between multiple bots
- Make all bots appear as a single bot
This template is used by my other discord bot projects:
- image-caption-ai
- aau-schedule-scraping
- google-drive-service
- corona-stats
- reddit-service
- chart-service
- A global
!help
command that auto-generates a message giving an overview of all command categories. - Auto-generated help messages for all command categories. Simply call
!help <command_category
. - Audio player with search functionality that dynamically loads all audio files placed in a specified folder for each bot.
- Get status nofications for each bot by configuring a developer guild.
- Registration and identification of all bots running in the microservice architecture. This ensures only a single bot answers the global
!help
command. - Docker and Docker Swarm commands for the Developer that provides an overview of the docker containers and VM's running in the microservice arhitecture.
- Disposing of services according to their specified scopes after command has been executed (...as they should, but apparently Discord.NET is not doing this for you ATM)
- Auto-delete of user commands and bot replies after a default time period.
- Set default and custom command prefix for every guild.
- Database integration that can be extended with custom entities.
A command category is only included in the global help command, if the command module class representing the category is decorated with the Group
and Summary
attributes.
Group
should specify the category name. Summary
should give a description of the category. As such, a category can be excluded from the overview e.g. by not decorating it with a Summary
attribute.
--INSERT EXAMPLE IMAGE HERE
Required:
- A help message for all commands in a category is only provided if the command module class representing the category is decorated with the
Group
andSummary
attributes. - A command is only included in the help message if it is decorated with the
Summary
attribute. The content of theSummary
attribute for each command should give a description of the command. The description is included just below the command call specification.
Optional:
- If the command module is decorated with the
Alias
attribute, the aliases will be included in the top of the help message together with the default command name. - If the command module is decorated with the
Remarks
attribute, the content will be included in the top of the help message after aliases. - The command call specification will be displayed with command parameters in snake_case. This can be overriden by a custom parameter specification by decorating the individual command with a
Summary
attribute containing the custom parameter text. - If a command is decorated with the
Remarks
attribute, the content will be included after the command description.
The commands will appear in the help message following the order they are declared in the command module class.
All this behaviour can be overridden for a specific command category by decorating your own custom help command with a Priority
attribute of 1 or higher.
--INSERT EXAMPLE IMAGES HERE
- Simply specify the name of the folder that contains audio when configuring the bot. Audio can now be played using the
AudioCient
as a dependency in a command module. - Use the XXX method to get the audio file that best matches the requested audio name according to the order: 'exact match', 'starts with' and 'contains'.
- Optimized by using an internal cache of sounds available in order to minimize I/O. It is possible to request a cache update if new sounds are added on runtime. Simply call
GetAvailableAudioNames
with the optional parameterupdateCache
set totrue
.
--LINK TO EXAMPLE PROJECT ON HOW TO USE--
It is possibly to specify a default delay for when messages should be deleted. This feature applies to both the command messages issued by the user and the replies issued by the bot. Futhermore, it is also possible to override the default and specify a custom deletion delay for each individual reply if desired. Of course, replies can also be persistent.
The idea is that all bot projects reference the TemplateBot
project and create an instance of the DiscordBot
class, which also means that they will share the same bot token.
However, certain functionality must be provided by one bot only e.g. a global !help
command. To agree on the bot which will react on !help
a bot is promoted to main bot whereas the other bots will be secondary bots. It is the responsibility of the main bot to generate a help message that contains all command categories from all bots in the microservice architecture. This is ensured by letting all secondary bots register their command categories at the main bot at startup.
The internal architecture is based on the MVC-pattern following the principles from Domain-Driven Design (DDD).
A brief overview of the layers:
Core (Model): Business logic. Represents domain objects and services.
Messages (View): Represents the Discord messages to be returned to a Discord guild i.e. a "View" is simply a formatted string to be interpreted by the Discord UI client.
Commands (Controller): Recieves incoming Discord commands which are then delegated to Core. The result from Core is represented as a Discord message (a View) and returned to the client.
Infrastructure: Data persistence and external web services.
TODO:
- Insert architecture illustration.
Please see the folder Config_Example
for an example of the required configuration files and values. Here you will find configuration files for the Production and Development environment as well Docker and Localhost. Rename the folder to Config
in order to load the configuration files at startup.
- Create one main bot and in its'
Config/appsettings.json
setIsMainBot: true
- Create zero to many secondary bots and in its'
Config/appsettings.json
setIsMainBot: false
I recommend creating two bots on Discord - one for development and one for production. The development bot should only have access to Discord guilds created for testing.
Place the production bot token in appsettings.Production.json
and the development bot token in appsettings.Development.json
:
"Discord": {
"BotToken": "YOUR_BOT_TOKEN"
}
The bot uses a local SQLite database for development. You should use a database server for production such as PostgreSQL. Insert the connection string for the production database in appsettings.Production.json
.
"DbConnectionString": "YOUR_CONNECTION_STRING"
The project uses Serilog for logging. Change the logging configuration defined in appsettings.json
or you can leave it as is.
It is possible to log using Elastic Stack (Elastic Search, Kibnana and Beats) - Dockerfiles are included.
Currently, a dashboard for the Discord bot is available in Kibana as a custom dashboard that reads log messages from the bot and display useful statistics.
⚠️ Remember to set up configuration first!
Either run the project from source or use the provided docker-compose.yml
to run it in Docker using the Docker Compose tool.
Clone the project:
git clone https://github.com/roedebaron/discord-bot.git
cd template-bot/TemplateBot
First, set up a postgres database for your platform. Then run the following commands:
- Start up the postgres database and make sure it is ready
- Run
dotnet run
. This will automatically download all dependencies, build the project and then run the service. - If no other port has been specified in the configuration, the service is now running on port 5000.
- Run
docker-compose up
to build the images and run the containers in attached mode. - If no other port has been specified in the configuration, the service is now running on port 5000.
Usage section TODO:
- Overview of all commands with link to example section
- Example section with commands
- Insert screenshot, demo gif, code examples etc.