-
Notifications
You must be signed in to change notification settings - Fork 3
Your first bot
Ok we have following scenario: You are a normal Discord user like me and think "Hey how do I create a bot for Discord?" or "I like to create my own bot which ...". Than you search "discord create bot" and you find the official API documentation and you have no plan where to getting started. (That's was my first mind, because I wanted to create fast and easy a bot). But luckily there are users like me or others, I'm not the only one, who have written an implementation. And this side should help you to create a simple bot and help you to understand the fundamentals of this library.
This chapter concentrates on the working with the library to create a simple "Hello World!"-bot. This bot can receive a command from a user and replies with "Hello World!".
Before you can to begin to write your own bot you need to register the bot by Discord.
- You need a Discord Account. (I know you have one, because why you should write a bot for Discord, if you don't know or use Discord?)
- You need to go to this site. You must login with your Discord account in the web to use this site.
- You now see this website where you can see all your bots and applications you have registered. Now click on "New Application". After you clicked the button you must enter a name and hit "Create".
- Now you see this page. Where you can add an app image(This is not the profile picture of the bot) and a description for the bot. You also see the client ID of the bot. In the left side bar you find the entry "Bot".
- Next click the "Add Bot" button to create the bot.
- Scroll down and activate the
Server Members Intent
option. This is necessary to use the rights managements system of the library. - You can now copy the token of the bot. This token is needed for the library to initialize.
**ATTENTION: DON'T SHARE THIS TOKEN WITH ANYBODY!!!**
After you have received your token we can begin to create our own bot. You can follow this guide to understand what each call of the library do or you can checkout this repo and copy the project_template
folder to create your first bot.
The library is designed to handle all low level stuff. This means all events and objects of Discord are handled by the library and the relation between objects like Member and Guild(Server) is managed internally. The user, you the developer, is informed by this events over controllers. These controllers get all events like user joined a channel or a user leave a channel. So let's begin to write our own controller.
Botcontroller.hpp
#ifndef BOTCONTROLLER_HPP
#define BOTCONTROLLER_HPP
#include <controller/IController.hpp>
using namespace DiscordBot;
class CBotController : public IController
{
public:
CBotController(IDiscordClient *client) : IController(client) {}
virtual ~CBotController() {}
};
#endif
Maybe you think: "Hey that was easy and so unnecessary. Why the heck I need this empty class?". These question is justified, maybe I like that the user need to implement unnecessary interfaces. But how I mentioned earlier all events from Discord are routed to this controller. You can go inside the IController.hpp
of the library to see what events you can received. Next we create the main for our bot.
Note: Since version 2.0.0-alpha it's necessary to call the base constructor with the IDiscordClient
object.
main.cpp
#include <IDiscordClient.hpp>
#include <BotController.hpp>
using namespace DiscordBot;
int main(int argc, char const *argv[])
{
DiscordClient client = IDiscordClient::Create("API-TOKEN");
client->RegisterController<CBotController>();
//Runs the loop until the Quit() method of the client is called.
client->Run();
return 0;
}
That's not much code but a huge amount to explain. First we include the client interface for Discord and our controller class we have written earlier. Inside the main
we first create a client with our token we have create in the Prerequisites
step. (You can also add intents for the bot as second parameter.) Next we register our controller.
Note: Every client can only have one controller.
Now we can run our bot. Inside the terminal you should see following message(The URL and Date/Time can be different):
[ 2020-05-23 17:57:17 ] [ info ] Connected with Discord! wss://gateway.discord.gg/?v=6&encoding=json
This message means your bot is successfully connected to Discord and you should see him in the member list of your Guild as online. Maybe you think "Cool stuff, but where are the commands for the bot?". Ok a very justified question. The answer is simple currently there are no commands. But lets move on to create our first one. First we need to create a command handler class/controller.
HelloCommand.hpp
#ifndef HELLOCOMMAND_HPP
#define HELLOCOMMAND_HPP
#include <controller/ICommand.hpp>
#include <IDiscordClient.hpp>
using namespace DiscordBot;
class CHelloCommand : public ICommand
{
public:
CHelloCommand(IDiscordClient *client) : m_Client(client)
{
//Registers the function which handels a command.
RegisterCommandHandler("hello", std::bind(&CHelloCommand::Hello, this, std::placeholders::_1));
}
virtual ~CHelloCommand() {}
private:
IDiscordClient *m_Client;
void Hello(CommandContext ctx)
{
m_Client->SendMessage(ctx->Msg->ChannelRef, "Hello World!");
}
};
#endif
What we see in this code snippet? First we see a class CHelloCommand
which inhirets from the ICommand
interface. This is necessary to call commands. The commands are internally routed to the right method of the class. Next we see a constructor which takes a IDiscordClient
interface as parameter. This is necessary to send a message into the chat. This parameter is set with a depency injection like pattern. Inside the constructor we see this line RegisterCommandHandler("hello", std::bind(&CHelloCommand::Hello, this, std::placeholders::_1));
. This line creates the routing from the command hello
to the method void Hello(CommandContext ctx)
. You can register any command with this kind of registration.
At the last step we need to register our command handler class/controller. This registration is made inside the CBotController
from earlier.
Botcontroller.hpp
#ifndef BOTCONTROLLER_HPP
#define BOTCONTROLLER_HPP
#include <controller/IController.hpp>
#include <HelloCommand.hpp>
using namespace DiscordBot;
class CBotController : public IController
{
public:
CBotController(IDiscordClient *client) : IController(client) {}
{
Prefix = "!"; //Prefix for the command.
}
void OnReady() override
{
//Registers a new command, with description for the builtin help command.
RegisterCommand<CHelloCommand>({"hello", "Writes \"Hello World!\" into the channel", 0, "", AccessMode::EVERYBODY}, Client);
}
virtual ~CBotController() {}
};
#endif
Inside the constructor we set the command prefix. This prefix introduces a command which the bot should handle. Maybe you have seen it before by other bots where you type commands like !help
. We see after the constructor a new method. This is a event of the library which is called after the bot is connect to discord. Inside this event we register our CHelloCommand
class/controller and bind it to the hello
command. You see the first parameter is an initializer list which takes 4 parameters. The first one is the command itself. The second is the description for the command, which will be print by the builtin help
command(h
or help
as command). As third parameter we have the amount of command parameter(e.g. !say Hallo Welt
). For the hello command we don't have any parameter.(-1 is null or more.) Following parameter is the delimiter for the command parameters. The last one is the default access mode for the command. This allows you to predefine the access of the command by users. The access mode can changed by the owner of the server. As i mentioned earlier the parameter for the constructor of the CHelloCommand
are injected over a kind of dependency injection. These parameter you can see at the last parameter of the RegisterCommand
call. We inject the current client to the call.(This client is a attribute of IController
interface and is set before after OnReady is called.). If you now start your bot and type !hello
into the chat, the bot should answer Hello World!
.
Note: Since version 2.0.0-alpha it's not necessary anymore to set the prefix. The default one is !
. Also since this version the rights management system is integrated, which means your commands needs a default access mode.
You have made it to the end of the first tutorial. You know now how to initialize the library and create your own command.
Hopefully this tutorial was understandable, if not please open an issue so I can correct it.