Due to discord's decision to enforce slash commands for bots, I will stop developing this project. This means that I won't fix any issues or bugs nor add new features. The project will remain on GitHub but it will be achieved.
The main reason I took this decision is that converting the bot to use slash commands would require me to rewrite the entire command logic. I neither have the time nor the motivation to rewrite major parts of the code base. On top of that dynoBot is quite maintenance heavy, especially in regard of the music streaming module which depends on a lot of other npm packages that tend to break.
Therefore, I will sadly put this project to rest.
dynoBot is a modular Discord bot using JavaScript and optionally also Python and Lua. It is built in a way that creating new modules can be done with ease in a scripting language you prefer.
The idea behind the bot is to create the modules you need by yourself with a minimum amount of effort. Therefore, dynoBot can be considered as a framework which handles everything related to the discord api, so you can immediately start developing your own modules.
Nevertheless, dynoBot can be used without writing a single line of code as long as the included modules are all you need.
The bot has currently following modules:
- music bot with Spotify, Apple Music and YouTube playlist support
- remote control rcon game servers
- currency conversion
- WolframAlpha calculations
- send wake-on-lan signals to start servers or other devices in your local network
You can see all available commands by typing "@BotName help" in the discord chat. Alternatively you can take a look at the commands.json file.
First you need nodejs and optionally python3 for python modules and lua for lua modules.
After the installation, clone this repository and run npm install
within the dynoBot
folder. It should install all required dependencies.
To run the discord bot, you'll have to add the security.json
file within the directory dynoBot/cfg
.
It should look like this:
{
"token": "your discord bot token"
}
IMPORTANT: When you fork this project, don't upload the security.json to your repository. This would allow others to steal your discord token.
If you want to use the Wolfram|Alpha module, you'll need their API key in the security.json
as well.
You can request a free Wolfram|Alpha API key here.
With the API key, your security.json should look like this:
{
"token": "your discord bot token",
"wolframAlphaAPI": "your api key"
}
As a default, all logs are written to the console.
If you want the logs to be written to log files, you have to enable logging in the security.json
like this:
{
"token": "your discord bot token",
"logging": true
}
Now you can start the bot by using the command node main.js
within the directory dynoBot
.
You can create modules in JavaScript, Python or Lua. There are two types of modules, a chat module and a hook module. A chat module is executed every time a user sends a message with the corresponding command. A hook is automatically executed in a specific interval. Below I will show you how to create them in JavaScript, Python and Lua. Alternatively you can take a look at the example modules for JavaScript, Python and Lua included in the project.
JavaScript, Python and Lua modules need an entry in the commands.json file looking like this:
{
"group": "command-group-name",
"type": "python",
"regex": "py-example|python example",
"help": "python example",
"path": "src/py-modules/example-python.py",
"hidden": false
}
The content of the help property will be used for the command list. If it does not exist, the regex property will be used.
The group property can be used to allow filtering while using the help command. For example there is a group called "basic" including all built-in core commands. If you want to see only commands of the "basic" group in the command list, use " help" instead of the normal help command.
Setting hidden to true will exclude the command from the command list.
The JavaScript module has direct access to the discord.js wrapper. The base structure of a module looks like this:
module.exports = {
run: function(msg, client) {
msg.getTextChannel().send("I received these parameters: " + msg.getContentArray());
}
};
The code executed when the module is called belongs into the run function. The parameters msg and client are by the chatbot-api-wrapper. You can find further information about the implementation there.
The Python module has no access to the discord.js wrapper but gets the msg.contentArray
and msg.aRegexGroups
.
The base structure looks like this:
import sys
msg = sys.argv[1].split(",") # Array of input parameters
regexGroups = sys.argv[2].split(",") # Array of input regex groups
# insert code to handle the input parameters here
print("I received these parameters: " + str(msg)) # This will be the msg that the bot sends
print("These are the regex groups" + str(regexGroups)) # This is a second message that the bot sends
sys.stdout.flush() # cleanup
As you can see, the print makes the bot send a message.
The Lua module has also no access to the discord.js wrapper but gets the msg.contentArray
and msg.aRegexGroups
.
The base structure looks like this:
-- Import lua module helper for splitting strings into arrays
require "src/utils/luaUtils"
local sMessage = arg[1] -- String of input parameters
local sRegexGroups = arg[2] -- String of input regex groups
local aMessage = utils.splitString(sMessage, ",") -- Array of input parameters
local aRegexGroups = utils.splitString(sRegexGroups, ",") -- Array of input regex groups
-- Insert code to handle the input parameters here
--This will be the msg that the bot sends
print("I received these parameters: [" .. tostring(aMessage[1]) .. ", " .. tostring(aMessage[2]) .. "]")
--This is a second message that the bot sends
print("These are the regex groups: [" .. tostring(aRegexGroups[1]) .. "]")
As you can see, the print makes the bot send a message. Overall Lua modules are pretty similar to Python modules.
JavaScript and Python modules both need an entry in the hooks.json file looking like this:
"technicalHookName": {
"type": "js",
"name": "hookName",
"path": "src/js-modules/yourModule.js",
"channel": 0,
"interval": 10000,
"running": false
}
The JavaScript module has access to the channel object of the discord.js wrapper. The code executed when the module is called belongs into the hook function.
module.exports = {
hook: function(channel) {
channel.send("This js message is automatically sent in a specific interval");
}
};
The hook function is executed when the hooks.json has the an existing channel and is running.
The Python module has no access to the channel object, it receives no inputs. It just runs the python script and every call of print creates a bot message. It should look like this:
import sys
# insert code to handle the input parameters here
# This will be the msg that the bot sends
print("This py message is automatically sent in a specific interval")
sys.stdout.flush() # cleanup
The Lua module has also no access to the channel object, it receives no inputs. It just runs the lua script and every call of print creates a bot message. It should look like this:
-- Insert code here
-- This will be the msg that the bot sends
print("This lua message is automatically sent in a specific interval.")
This is again similar to Python modules.
Yes, I will review your code and if it's good, I'll merge it into the master. Please adapt your code style regarding already existing modules.
Yes, that's also ok. But it would be nice if more people could profit from your work.