The etf_parser class can serialise and deserialise ETF (Erlang Term Format) into and out of an nlohmann::json object, so that layers above the websocket don't have to be any different for handling ETF
Base event parameter struct. Each event you receive from the library will have its parameter derived from this class. The class contains the raw event data, and a pointer to the current shard's dpp::discord_client object. You can also use this object to cancel the current event, meaning that any listeners after yours do not get notified of the current event if you call it
Handles routing of an event to multiple listeners. Multiple listeners may attach to the event_router_t by means of operator(). Passing a lambda into operator() attaches to the event
Represents a thread in the thread pool handling requests to HTTP(S) servers. There are several of these, the total defined by a constant in queues.cpp, and each one will always receive requests for the same rate limit bucket based on its endpoint portion of the url. This makes rate limit handling reliable and easy to manage. Each of these also has its own mutex, so that requests are less likely to block while waiting for internal containers to be usable
An interaction represents a user running a command and arrives via the dpp::cluster::on_interaction_create event. This is further split into the events on_form_submit, on_slashcommand, on_user_context_menu, on_button_click, on_select_menu, etc
Extremely light coroutine object designed to send off a coroutine to execute on its own. Can be used in conjunction with coroutine events via event routers, or on its own
Represents an interface for an object that can optionally implement functions for converting to and from nlohmann::json. The methods are only present if the actual object also has those methods
Represents a multipart mime body and the correct top-level mime type If a non-multipart request is passed in, this is represented as a plain body and the application/json mime type
Details of a command parameter used in registration. Note that for non-slash commands optional parameters can only be at the end of the list of parameters
Dpp::resolved_user contains both a dpp::guild_member and a dpp::user. The user can be used to obtain in-depth user details such as if they are nitro, and the guild member information to check their roles on a guild etc. The Discord API provides both if a parameter is a user ping, so we offer both in a combined structure
Represents a role within a dpp::guild. Roles are combined via logical OR of the permission bitmasks, then channel-specific overrides can be applied on top, deny types apply a logic NOT to the bit mask, and allows apply a logical OR
A timed_listener is a way to temporarily attach to an event for a specific timeframe, then detach when complete. A lambda may also be optionally called when the timeout is reached. Destructing the timed_listener detaches any attached event listeners, and cancels any created timers, but does not call any timeout lambda
A user with additional fields only available via the oauth2 identify scope. These are not included in dpp::user as additional scopes are needed to fetch them which bots do not normally have
Represents a connection to a voice channel. A client can only connect to one voice channel per guild at a time, so these are stored in a map in the dpp::discord_client keyed by guild_id
Experimental class to co_await on a bunch of awaitable objects, resuming when the first one completes. On completion, returns a result object that contains the index of the awaitable that finished first. A user can call result::index() and result::get<N>() on the result object to get the result, similar to std::variant
The etf_parser class can serialise and deserialise ETF (Erlang Term Format) into and out of an nlohmann::json object, so that layers above the websocket don't have to be any different for handling ETF
Base event parameter struct. Each event you receive from the library will have its parameter derived from this class. The class contains the raw event data, and a pointer to the current shard's dpp::discord_client object. You can also use this object to cancel the current event, meaning that any listeners after yours do not get notified of the current event if you call it
Handles routing of an event to multiple listeners. Multiple listeners may attach to the event_router_t by means of operator(). Passing a lambda into operator() attaches to the event
Represents a thread in the thread pool handling requests to HTTP(S) servers. There are several of these, the total defined by a constant in queues.cpp, and each one will always receive requests for the same rate limit bucket based on its endpoint portion of the url. This makes rate limit handling reliable and easy to manage. Each of these also has its own mutex, so that requests are less likely to block while waiting for internal containers to be usable
An interaction represents a user running a command and arrives via the dpp::cluster::on_interaction_create event. This is further split into the events on_form_submit, on_slashcommand, on_user_context_menu, on_button_click, on_select_menu, etc
Extremely light coroutine object designed to send off a coroutine to execute on its own. Can be used in conjunction with coroutine events via event routers, or on its own
Represents an interface for an object that can optionally implement functions for converting to and from nlohmann::json. The methods are only present if the actual object also has those methods
Represents a multipart mime body and the correct top-level mime type If a non-multipart request is passed in, this is represented as a plain body and the application/json mime type
Details of a command parameter used in registration. Note that for non-slash commands optional parameters can only be at the end of the list of parameters
Dpp::resolved_user contains both a dpp::guild_member and a dpp::user. The user can be used to obtain in-depth user details such as if they are nitro, and the guild member information to check their roles on a guild etc. The Discord API provides both if a parameter is a user ping, so we offer both in a combined structure
Represents a role within a dpp::guild. Roles are combined via logical OR of the permission bitmasks, then channel-specific overrides can be applied on top, deny types apply a logic NOT to the bit mask, and allows apply a logical OR
A timed_listener is a way to temporarily attach to an event for a specific timeframe, then detach when complete. A lambda may also be optionally called when the timeout is reached. Destructing the timed_listener detaches any attached event listeners, and cancels any created timers, but does not call any timeout lambda
A user with additional fields only available via the oauth2 identify scope. These are not included in dpp::user as additional scopes are needed to fetch them which bots do not normally have
Represents a connection to a voice channel. A client can only connect to one voice channel per guild at a time, so these are stored in a map in the dpp::discord_client keyed by guild_id
Experimental class to co_await on a bunch of awaitable objects, resuming when the first one completes. On completion, returns a result object that contains the index of the awaitable that finished first. A user can call result::index() and result::get<N>() on the result object to get the result, similar to std::variant
This tutorial assumes you are using Ubuntu. You might use other distros if you prefer, but keep in mind the setup process might be different! This tutorial also teaches you how to use DPP with CMake, using the JetBrains IDE CLion. If you have not installed CLion, You can download CLion here. If you do not have DPP installed, visit this page on how to setup the project using a precompiled version of DPP. If you want to use source and haven't set that up, look towards this page on how to do so. This tutorial will not teach you how to setup CMake and will assume you have already done so.
-
+
Add an example program
Open up CLion and open the folder for your bot. You may notice that CLion will start doing the whole CMake process and it will create a folder called cmake-build-debug, this is normal so don't be alarmed! It is just CLion registering all the CMake stuff so it can build and give you auto-suggestions.
Now, you can open your main.cpp file. If you have code there, then you're one step ahead! If not, copy and paste the following example program in the main.cpp and set your bot token (see Creating a Bot Token). Here's how your main.cpp file should look:
To create a basic bot using Visual Studio 2019 or Visual Studio 2022, follow the steps below to create a working skeleton project you can build upon.
If you prefer a video tutorial, you can watch the video below! Otherwise, scroll past and keep reading!
-
+
Video Tutorial
-
+
Text Tutorial
Make sure you have Visual Studio 2019 or 2022. Community, Professional or Enterprise work fine. These instructions are not for Visual Studio Code. You can download the correct version here. Note that older versions of Visual Studio will not work as they do not support enough of the C++17 standard.
@@ -132,7 +132,7 @@
-
+
Troubleshooting
If you get an error that looks like this:
1>MyBot.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: class dpp::async<struct dpp::confirmation_callback_t>
This tutorial will assume that you have already installed DPP. If you haven't, please head over to this page, or any install page that matches your OS. If you want to use source, then continue your journey over at this page for a full explanation into using CMake with source.
-
+
1. Toolchain
Before continuing, you will need to install cmake on your system. To be sure that cmake is installed, you can type the following command:
$ cmake --version
cmake version 3.22.1
If your CMake version is not as shown above then don't worry! You can still follow along, even if you're ahead or behind!
-
+
2. Create a CMake project
In an empty directory, create the following files and directories:
-
+
3. Configure CMake
You'll need to modify the CMakeLists.txt to tell CMake what it's looking for, and other information.
Here is an example CMake configuration, you can adapt it according to your needs:
Now that we have our all our cmake stuff setup and we've got our code in place, we can initalise CMake. You'll want to go inside the build/ directory and do cmake ...
Once that's completed, you'll want to head back to your up-most folder (where all the folders are for your bot) and run cmake --build build/ -j4 (replace -j4 with however many threads you want to use). This will start compiling your bot and creating the executable.
This page assumes you are the root user. If you are not, start the package install commands with sudo, along with make install. You will need sudo installed if you are not the root user.
-
+
1. Toolchain
Since the project uses CMake, you'll need to install it! If you don't have it, you can do the following:
pkg install cmake
-
+
2. Install Voice Dependencies (Optional)
If you wish to use voice support, you'll need to install opus and libsodium:
First, you need to install opus.
cd /usr/ports/audio/opus
@@ -114,21 +114,21 @@
Then, you need to install libsodium.
cd /usr/ports/security/libsodium
make && make install
-
+
3. Build Source Code
cmake -B ./build
cmake --build ./build -j8
Replace the number after -j with a number suitable for your setup, usually the same as the number of cores on your machine. cmake will fetch any dependencies that are required for you and ensure they are compiled alongside the library.
-
+
4. Install Globally
cd build
make install
-
+
5. Installation to a Different Directory (Optional)
If you want to install the library, its dependencies and header files to a different directory, specify this directory when running cmake:
cmake .. -DCMAKE_INSTALL_PREFIX=/path/to/install
Then once the build is complete, run sudo make install to install to the location you specified.
-
+
6. Using the Library
Once installed, you can make use of the library in standalone programs simply by including it and linking to it:
If the bot fails to start and instead you receive an error message about being banned from the Discord API, there is little to be done about this. These bans are temporary but because Replit is a shared platform, you share an IP address with many thousands of bots, some abusive and some badly written. This will happen often and is outside of the control of yourself and us. However, you can try to mitigate this by typing kill 1 in the shell. This is not guaranteed to work, and you might need to try it a few times. If it still does not work, then we recommend you obtain some affordable non-free hosting instead.
You might not need to build a copy of the library for Linux - precompiled deb files for 64 bit and 32 bit Debian and Ubuntu are provided in the GitHub version releases. Unless you are on a different Linux distribution which does not support the installation of deb files, or wish to submit fixes and enhancements to the library itself you should have an easier time installing the precompiled version instead.
-
+
1. Build Source Code
cmake -B ./build
cmake --build ./build -j8
Replace the number after -j with a number suitable for your setup, usually the same as the number of cores on your machine. cmake will fetch any dependencies that are required for you and ensure they are compiled alongside the library.
-
+
2. Install to /usr/local/include and /usr/local/lib
cd build
sudo make install
-
+
3. Installation to a Different Directory
If you want to install the library, its dependencies, and header files to a different directory, specify this directory when running cmake:
cmake .. -DCMAKE_INSTALL_PREFIX=/path/to/install
Then once the build is complete, run make install to install to the location you specified.
-
+
4. Using the Library
Once installed to the /usr/local directory, you can make use of the library in standalone programs simply by including it and linking to it:
This page assumes you are the root user. If you are not, start the package install commands with doas, along with make install.
-
+
1. Toolchain
Since the project uses CMake, you'll need to install it! If you don't have it, you can do the following:
pkg_add cmake
-
+
2. Install Voice Dependencies (Optional)
If you wish to use voice support, you'll need to do the following:
pkg_add libsodium opus pkgconf
-
+
3. Build Source Code
cmake -B ./build
cmake --build ./build -j8
Replace the number after -j with a number suitable for your setup, usually the same as the number of cores on your machine. cmake will fetch any dependencies that are required for you and ensure they are compiled alongside the library.
-
+
4. Install Globally
cd build; make install
-
+
5. Installation to a Different Directory
If you want to install the library, its dependencies and header files to a different directory, specify this directory when running cmake:
cmake .. -DCMAKE_INSTALL_PREFIX=/path/to/install
Then once the build is complete, run make install to install to the location you specified.
-
+
6. Using the Library
Once installed to the /usr/local directory, you can make use of the library in CMake, without linking to a folder! You can't use this with clang++, nor g++, as OpenBSD seems to be broken on this end, so your only option from here is to use CMake. This isn't a bad thing, as we recommend people to use CMake anyways!
This project uses CMake to generate the makefiles. Install it with brew install cmake.
-
+
2. Install External Dependencies
brew install openssl pkgconfig
Note
Usually, you do not need pkgconfig. However, it seems that it throws errors about openssl without.
For voice support, additional dependencies are required:
brew install libsodium opus
-
+
3. Build Source Code
cmake -B ./build
cmake --build ./build -j8
Replace the number after -j with a number suitable for your setup, usually the same as the number of cores on your machine. cmake will fetch any dependencies that are required for you and ensure they are compiled alongside the library.
-
+
4. Install Globally
cd build
sudo make install
-
+
5. Installation to a Different Directory
If you want to install the library, its dependencies, and header files to a different directory, specify this directory when running cmake:
cmake .. -DCMAKE_INSTALL_PREFIX=/path/to/install
Then once the build is complete, run sudo make install to install to the location you specified.
-
+
6. Using the Library
Once installed, you can make use of the library in standalone programs simply by including it and linking to it:
If you are absolutely sure you need this guide, read on:
Make sure you have Visual Studio 2019 or Visual Studio 2022. The Community, Professional or Enterprise versions all work, however you will probably want to install Community. You do NOT want to use Visual Studio Code for this. You can download the correct version here.
@@ -126,13 +126,13 @@
-
+
Troubleshooting
If you do not have an option to open the CMakeLists.txt, ensure that you have installed the C++ development portions of Visual Studio (not just web development portions) with at least the default options.
After compilation you can directly reference the compiled project in your own CMakeLists.txt as a library or use the lib/dll/headers as you wish. Note that openssl and zlib will also be an indirect dependency of your program (as DLL files) and should be copied alongside dpp.dll.
Discord's intended way to manage permissions for commands is through default member permissions. You set them using dpp::slashcommand::set_default_permissions when creating or updating a command to set the default permissions a user must have to use it. However, server administrators can then overwrite these permissions by their own restrictions.
The corresponding code to create a command with default permissions would look something like this:
Each command option is a command line parameter. It can have a type (see dpp::command_option_type),...
Definition: appcommand.h:203
-
+
Checking Permissions on Your Own
If you want to check permissions on your own, the easiest way to check if a member has certain permissions in interaction events is by using the dpp::interaction::get_resolved_permission function. The resolved list contains associated structures for the command and does not use the cache or require any extra API calls. Note that the permissions in the resolved set are pre-calculated by Discord and taking into account channel overwrites, roles and admin privileges. So no need to loop through roles or stuff like that.
When using default permissions you don't necessarily need to check the issuing user for any permissions in the interaction event as Discord handles all that for you. But if you'd sleep better...
-
+
From Parameters
The resolved set also contains the permissions of members from command parameters.
For example, let's say you want to prohibit people from banning server admins with your ban command.
You also might want to check if the bot itself has the ban permission before processing the command further. You can access the bot's permissions in the dpp::interaction::app_permissions field.
on voice client platform event After a client connects, or on joining a vc, you will receive the platform type of each client. This is either desktop or mobile. More...
on voice client platform event After a client connects, or on joining a vc, you will receive the platform type of each client. This is either desktop or mobile.
+
Note
Use operator() to attach a lambda to this event, and the detach method to detach the listener using the returned ID. The function signature for this event takes a single const reference of type voice_client_disconnect_t&, and returns void.
Returns the privacy code for the end to end encryption scheme ("DAVE"). if end-to-end encryption is not active, or is not yet established, this will return an empty string. More...
Returns the privacy code for the end to end encryption scheme ("DAVE"). if end-to-end encryption is not active, or is not yet established, this will return an empty string.
+
Returns
A sequence of six five-digit integers which can be matched against the Discord client, in the privacy tab for the properties of the voice call.
True if the user specified is in a vc, false if they aren't
Note
This is NOT a synchronous blocking call! The bot isn't instantly ready to send or listen for audio, as we have to wait for the connection to the voice server to be established! e.g. wait for dpp::cluster::on_voice_ready event, and then send the audio within that event.
Represents a connection to a voice channel. A client can only connect to one voice channel per guild at a time, so these are stored in a map in the dpp::discord_client keyed by guild_id.
It can spawn a thread to establish the connection, so this is NOT a synchronous blocking call! You shouldn't call this directly. Use a wrapper function instead. e.g. dpp::guild::connect_member_voice