Warden is a discord bot for the Anti-Xeno Initiative Discord Server. Based on Discord.js warden is a combination of systems that culminate in a relatively advanced custom built discord bot for the needs of the AXI.
The bot was overhauled and provides a single codebase where multiple bots can be ran from. Recommend running them from different hostnames as they are coded to detect the hostname they are configured to run on which can be coded from your own point of view. It is modular after all.
Contains a lot of comments about how the modularity works. Please review that section. It will get added to this readme in the future.
Setting up a local copy of the bot for development. If you are new to development, you will need the following recommended programs to run a local version of the bot.
npm i
to install dependencies.Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
. PS2 may also need this setting to operate. Use a test environment VM if you have security concerns and ensure you reset the execution policy back to what you had previoiusly to Signed
. https://stackoverflow.com/questions/54776324/powershell-bug-execution-of-scripts-is-disabled-on-this-system for more information regarding this.npm start
in command line or terminal.The SETUP.ps1
file will create a .env
file in your root directory, if you need to make any changes, edit the variables in this file.
The SETUP.ps1
file will also modify the config.json
, which you will need to review.
npm install pm2 -g
{
"apps": [
{
"name":"Warden",
"script": "index.js",
"ignore_watch": [".env",".git*",".ps1"],
"watch": true,
"exec_mode": "fork",
"max_restarts": 1,
"min_uptime": 5000
}
]
}
pm2 start pm2-config.json --watch
pm2 logs
pm2 stop all
To create a new command, make a new .js file in one of the subfolders, and copy the necessary module.exports content into it. ducc.js is a great example command.
Note: Commands will ONLY be loaded if they are in a subfolder. Any command file not in a subfolder will cause the command handler to fail.
Commands are all stored in subfolders of the "../commands" folder, if they are not within a subfolder they will not be registered as a command and won't be detected by the command handler.
Each command is a seperate .js file setup as a module. Within the file are parameters that define what the command is, how it can be used and other details.
There are two types of commands that can be used with this bot Slash Commands
and Non-Slash Commands
. We prefer you try design commands as Slash commands as these are better supported and have better UI integration into Discord.
Within the file is an execute(message, args) {}
or execute(interaction) {}
function, this is where your code executes when the command is called by a user. The message
and args
or interaction
variables are defined by the type of command you created.
Use the following as a boilerplate for your commands.
Command name and description are defined in the data:
field, this feeds into discord to allow the slash command UI to make easy command browsing, here you can also specify special argument fields (more below).
module.exports = {
data: new Discord.SlashCommandBuilder()
.setName('myCommandName') // What the user types to call the command
.setDescription('myCommandDescription'), // The Discord Description for the command
permissions: 0,
execute(interaction) {
// Command Code
interaction.reply({ content: "Hello World!"}) // Replies to the user "Hello World".
},
};
You can set options for commands, this allows users to have extra inputs with each command. You can read more about this here: https://discordjs.guide/interactions/registering-slash-commands.html
Example with Slash Command Options:
module.exports = {
data: new Discord.SlashCommandBuilder()
.setName('myCommandName') // What the user types to call the command
.setDescription('myCommandDescription')
.addStringOption(option => option.setName('myArgument') // Create the option
.setDescription('Type Something Here!')
.setRequired(true)),
permissions: 0,
execute(interaction) {
// Command Code
let response = interaction.options.data.find(arg => arg.name === 'myArgument').value // Get the option from the command usage
interaction.reply({ content: response}) // Sends the option text back to the user as a reply.
},
};
A good example of this type of command is ./commands/wiki/wiki.js
or ./commands/math/mttot.js