스킵 구현

This commit is contained in:
2023-12-20 19:45:25 +09:00
parent 6503fd167b
commit 8a987320e0
775 changed files with 162601 additions and 135 deletions

View File

@@ -0,0 +1,46 @@
#
# D++ (DPP), The Lightweight C++ Discord Library
#
# Copyright 2021 Craig Edwards <support@brainbox.cc>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Example programs test compilation
# This build script is executed by a GitHub action to ensure all example
# programs compile correctly. It does not attempt to run them, as there
# is no way to know if the program successfully did its thing, plus
# examples do not have a valid token. This build script assumes the
# following system dependencies are available:
#
# g++-12 or later
# liboggz-dev
# libmpg123-dev
# dpp latest master with -DDPP_CORO=ON installed sytemwide
cmake_minimum_required (VERSION 3.16)
project(documentation_tests)
string(ASCII 27 Esc)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DDPP_CORO -std=c++20 -pthread -O0 -fPIC -rdynamic -DFMT_HEADER_ONLY -Wall -Wextra -Wpedantic -Werror -Wno-unused-parameter")
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0")
file(GLOB example_list ./*.cpp)
foreach (example ${example_list})
get_filename_component(examplename ${example} NAME)
message(STATUS "Found example '${Esc}[1;34m${examplename}${Esc}[m'")
add_executable(${examplename}_out ${example})
target_link_libraries(${examplename}_out dl dpp mpg123 oggz ogg opusfile opus)
include_directories(/usr/include/opus)
endforeach(example)

View File

@@ -0,0 +1,32 @@
#include <dpp/dpp.h>
int main() {
dpp::cluster bot("token");
bot.on_log(dpp::utility::cout_logger());
/* The event is fired when someone issues your commands */
bot.on_slashcommand([&bot](const dpp::slashcommand_t& event) {
/* Check which command they ran */
if (event.command.get_command_name() == "file") {
dpp::message msg(event.command.channel_id, "Hey there, I've got a new file!");
/* attach the file to the message */
msg.add_file("foobar.txt", dpp::utility::read_file("path_to_your_file.txt"));
/* Reply to the user with the message, with our file attached. */
event.reply(msg);
}
});
bot.on_ready([&bot](const dpp::ready_t& event) {
if (dpp::run_once<struct register_bot_commands>()) {
/* Create and register a command when the bot is ready */
bot.global_command_create(dpp::slashcommand("file", "Send a message with a file attached!", bot.me.id));
}
});
bot.start(dpp::st_wait);
return 0;
}

View File

@@ -0,0 +1,40 @@
#include <dpp/dpp.h>
int main() {
dpp::cluster bot("token");
bot.on_log(dpp::utility::cout_logger());
/* The event is fired when someone issues your commands */
bot.on_slashcommand([&bot](const dpp::slashcommand_t& event) {
/* Check which command they ran */
if (event.command.get_command_name() == "file") {
/* Request the image from the URL specified and capture the event in a lambda. */
bot.request("https://dpp.dev/DPP-Logo.png", dpp::m_get, [event](const dpp::http_request_completion_t & httpRequestCompletion) {
/* Create a message */
dpp::message msg(event.command.channel_id, "This is my new attachment:");
/* Attach the image to the message, only on success (Code 200). */
if (httpRequestCompletion.status == 200) {
msg.add_file("logo.png", httpRequestCompletion.body);
}
/* Send the message, with our attachment. */
event.reply(msg);
});
}
});
bot.on_ready([&bot](const dpp::ready_t& event) {
if (dpp::run_once<struct register_bot_commands>()) {
/* Create and register a command when the bot is ready */
bot.global_command_create(dpp::slashcommand("file", "Send a message with an image attached from the internet!", bot.me.id));
}
});
bot.start(dpp::st_wait);
return 0;
}

View File

@@ -0,0 +1,39 @@
#include <dpp/dpp.h>
int main() {
dpp::cluster bot("token");
bot.on_log(dpp::utility::cout_logger());
/* The event is fired when someone issues your commands */
bot.on_slashcommand([&bot](const dpp::slashcommand_t& event) {
/* Check which command they ran */
if (event.command.get_command_name() == "file") {
/* Create a message. */
dpp::message msg(event.command.channel_id, "");
/* Attach the image to the message we just created. */
msg.add_file("image.jpg", dpp::utility::read_file("path_to_your_image.jpg"));
/* Create an embed. */
dpp::embed embed;
embed.set_image("attachment://image.jpg"); /* Set the image of the embed to the attached image. */
/* Add the embed to the message. */
msg.add_embed(embed);
event.reply(msg);
}
});
bot.on_ready([&bot](const dpp::ready_t& event) {
if (dpp::run_once<struct register_bot_commands>()) {
/* Create and register a command when the bot is ready */
bot.global_command_create(dpp::slashcommand("file", "Send a local image along with an embed with the image!", bot.me.id));
}
});
bot.start(dpp::st_wait);
return 0;
}

View File

@@ -0,0 +1,67 @@
#include <dpp/dpp.h>
int main()
{
dpp::cluster bot("token");
bot.on_log(dpp::utility::cout_logger());
bot.on_ready([&bot](const dpp::ready_t & event) {
if (dpp::run_once<struct register_bot_commands>()) {
/* Create a new global command once on ready event */
bot.global_command_create(dpp::slashcommand("blep", "Send a random adorable animal photo", bot.me.id)
.add_option(
/* If you set the auto complete setting on a command option, it will trigger the on_autocomplete
* event whenever discord needs to fill information for the choices. You cannot set any choices
* here if you set the auto complete value to true.
*/
dpp::command_option(dpp::co_string, "animal", "The type of animal").set_auto_complete(true)
)
);
}
});
/* The interaction create event is fired when someone issues your commands */
bot.on_slashcommand([&bot](const dpp::slashcommand_t & event) {
/* Check which command they ran */
if (event.command.get_command_name() == "blep") {
/* Fetch a parameter value from the command parameters */
std::string animal = std::get<std::string>(event.get_parameter("animal"));
/* Reply to the command. There is an overloaded version of this
* call that accepts a dpp::message so you can send embeds.
*/
event.reply("Blep! You chose " + animal);
}
});
/* The on_autocomplete event is fired whenever discord needs information to fill in a command options's choices.
* You must reply with a REST event within 500ms, so make it snappy!
*/
bot.on_autocomplete([&bot](const dpp::autocomplete_t & event) {
for (auto & opt : event.options) {
/* The option which has focused set to true is the one the user is typing in */
if (opt.focused) {
/* In a real world usage of this function you should return values that loosely match
* opt.value, which contains what the user has typed so far. The opt.value is a variant
* and will contain the type identical to that of the slash command parameter.
* Here we can safely know it is string.
*/
std::string uservalue = std::get<std::string>(opt.value);
bot.interaction_response_create(event.command.id, event.command.token, dpp::interaction_response(dpp::ir_autocomplete_reply)
.add_autocomplete_choice(dpp::command_option_choice("squids", "lots of squids"))
.add_autocomplete_choice(dpp::command_option_choice("cats", "a few cats"))
.add_autocomplete_choice(dpp::command_option_choice("dogs", "bucket of dogs"))
.add_autocomplete_choice(dpp::command_option_choice("elephants", "bottle of elephants"))
);
bot.log(dpp::ll_debug, "Autocomplete " + opt.name + " with value '" + uservalue + "' in field " + event.name);
break;
}
}
});
bot.start(dpp::st_wait);
return 0;
}

View File

@@ -0,0 +1,60 @@
#include <dpp/dpp.h>
#include <sstream>
int main() {
/* Create bot */
dpp::cluster bot("token", dpp::i_default_intents | dpp::i_message_content); /* Because we're handling messages, we need to use the "i_message_content" intent! */
/* Create a cache to contain types of dpp::message */
dpp::cache<dpp::message> message_cache;
bot.on_log(dpp::utility::cout_logger());
/* Message handler */
bot.on_message_create([&message_cache](const dpp::message_create_t &event) {
/* Make a permanent pointer using new, for each message to be cached */
dpp::message* m = new dpp::message();
/* Store the message into the pointer by copying it */
*m = event.msg;
/* Store the new pointer to the cache using the store() method */
message_cache.store(m);
});
/* The event is fired when someone issues your commands */
bot.on_slashcommand([&bot, &message_cache](const dpp::slashcommand_t& event) {
/* Check which command they ran */
if (event.command.get_command_name() == "get") {
dpp::message* find_msg = message_cache.find(std::get<std::string>(event.get_parameter("message_id")));
/* If find_msg is null, tell the user and return. */
if (!find_msg) {
event.reply("There is no message cached with this ID");
return;
}
event.reply("This message had the following content: " + find_msg->content);
}
});
bot.on_ready([&bot](const dpp::ready_t& event) {
if (dpp::run_once<struct register_bot_commands>()) {
/* Create a new command. */
dpp::slashcommand newcommand("get", "Get the contents of a message that was cached via an id", bot.me.id);
/* Add a parameter option. */
newcommand.add_option(dpp::command_option(dpp::co_string, "message_id", "The ID of the message you want to find", true));
/* Register the command */
bot.global_command_create(newcommand);
}
});
/* Start bot */
bot.start(dpp::st_wait);
return 0;
}

View File

@@ -0,0 +1,89 @@
#include <dpp/dpp.h>
int main() {
dpp::cluster bot("Token Was Here", dpp::i_default_intents | dpp::i_message_content);
/* the second argument is a bitmask of intents - i_message_content is needed to get messages */
bot.on_log(dpp::utility::cout_logger());
/* The event is fired when someone issues your commands */
bot.on_slashcommand([&bot](const dpp::slashcommand_t& event) {
if (event.command.get_command_name() == "msgs-get") {
int64_t limit = std::get<int64_t>(event.get_parameter("quantity"));
/* get messages using ID of the channel the command was issued in */
bot.messages_get(event.command.channel_id, 0, 0, 0, limit, [event](const dpp::confirmation_callback_t& callback) {
if (callback.is_error()) { /* catching an error to log it */
std::cout << callback.get_error().message << std::endl;
return;
}
auto messages = callback.get<dpp::message_map>();
/* std::get<dpp::message_map>(callback.value) would give the same result */
std::string contents;
for (const auto& x : messages) { /* here we iterate through the dpp::message_map we got from callback... */
contents += x.second.content + '\n'; /* ...where x.first is ID of the current message and x.second is the message itself. */
}
event.reply(contents); /* we will see all those messages we got, united as one! */
});
} else if (event.command.get_command_name() == "channel-create") {
/* create a text channel */
dpp::channel channel = dpp::channel()
.set_name("test")
.set_guild_id(event.command.guild_id);
bot.channel_create(channel, [&bot, event](const dpp::confirmation_callback_t& callback) -> void {
if (callback.is_error()) { /* catching an error to log it */
bot.log(dpp::loglevel::ll_error, callback.get_error().message);
return;
}
auto channel = callback.get<dpp::channel>();
/* std::get<dpp::channel>(callback.value) would give the same result */
/* reply with the created channel information */
dpp::message message = dpp::message("The channel's name is `" + channel.name + "`, ID is `" + std::to_string(channel.id) + " and type is `" + std::to_string(channel.get_type()) + "`.");
/* note that channel types are represented as numbers */
event.reply(message);
});
} else if (event.command.get_command_name() == "msg-error") {
bot.message_get(0, 0, [event](const dpp::confirmation_callback_t& callback) -> void {
/* the error will occur since there is no message with ID '0' that is in a channel with ID '0' (I'm not explaining why) */
if (callback.is_error()) {
event.reply(callback.get_error().message);
return;
}
/* we won't be able to get here because of the return; statement */
auto message = callback.get<dpp::message>();
event.reply(message);
});
}
});
bot.on_ready([&bot](const dpp::ready_t& event) {
if (dpp::run_once <struct register_global_commands>()) {
dpp::slashcommand msgs_get("msgs-get", "Get messages", bot.me.id);
constexpr int64_t min_val{1};
constexpr int64_t max_val{100};
msgs_get.add_option(
dpp::command_option(dpp::co_integer, "quantity", "Quantity of messages to get. Max - 100.")
.set_min_value(min_val)
.set_max_value(max_val)
);
dpp::slashcommand channel_create("channel-create", "Create a channel", bot.me.id);
dpp::slashcommand msg_error("msg-error", "Get an error instead of message :)", bot.me.id);
bot.global_bulk_command_create({ msgs_get, channel_create, msg_error });
}
});
bot.start(dpp::st_wait);
return 0;
}

View File

@@ -0,0 +1,24 @@
#include <dpp/dpp.h>
int main() {
dpp::cluster bot("token");
bot.on_log(dpp::utility::cout_logger());
/* We won't be performing any commands, so we don't need to add the event here! */
bot.on_ready([&bot](const dpp::ready_t & event) {
if (dpp::run_once<struct clear_bot_commands>()) {
/* Now, we're going to wipe our commands */
bot.global_bulk_command_delete();
/* This one requires a guild id, otherwise it won't know what guild's commands it needs to wipe! */
bot.guild_bulk_command_delete(857692897221033129);
}
/* Because the run_once above uses a 'clear_bot_commands' struct, you can continue to register commands below! */
});
bot.start(dpp::st_wait);
return 0;
}

View File

@@ -0,0 +1,27 @@
/*
* @brief This is a function that does some cool stuff.
* More stuff here will still go in brief!
* @warning This does nothing!
*/
func_name();
/*
* @brief This turns a name into a meme name!
*
* @param name The name of the user that you want to meme-ify.
* @return a meme name!
*/
std::string name_to_meme(const std::string& name) const;
/* -------------------- .cpp file -------------------- */
int main() {
/* We are now going to do some cool stuff. */
func_name();
/* Going to turn brain into a meme name.
* Why?
* Because why not. That's why.
*/
std::cout << name_to_meme("Brain") << "\n";
}

View File

@@ -0,0 +1,20 @@
void foo() {
if (a == b) {
c();
} else {
d();
}
while (true) {
// ...
}
switch (a) {
case 1:
c();
break;
case 2:
d();
break;
}
}

View File

@@ -0,0 +1,5 @@
stuff{}
.add_stuff()
.add_stuff();
event.reply("This reply function isn't indented!");

View File

@@ -0,0 +1,18 @@
class DPP_EXPORT my_new_class {
public:
int hats;
int clowns;
my_new_class& set_hats(int new_hats);
my_new_class& set_clowns(int new_clowns);
};
my_new_class& my_new_class::set_hats(int new_hats) {
hats = new_hats;
return *this;
}
my_new_class& my_new_class::set_clowns(int new_clowns) {
clowns = new_clowns;
return *this;
}

View File

@@ -0,0 +1,2 @@
dpp::my_new_class nc;
nc.set_hats(3).set_clowns(9001);

View File

@@ -0,0 +1,3 @@
std::vector<std::string> clowns = { "pennywise", "bobo" };
evaluate_clown(clowns[0], evilness(2.5, factor));

View File

@@ -0,0 +1,5 @@
class DPP_EXPORT my_new_class {
public:
int hats;
int clowns;
};

View File

@@ -0,0 +1,46 @@
#include <dpp/dpp.h>
/* To create a collector we must derive from dpp::collector. As dpp::collector is a complicated template,
* various pre-made forms exist such as this one, reaction_collector.
*/
class react_collector : public dpp::reaction_collector {
public:
/* Collector will run for 20 seconds */
react_collector(dpp::cluster* cl, dpp::snowflake id) : dpp::reaction_collector(cl, 20, id) { }
/* Override the "completed" event and then output the number of collected reactions as a message. */
virtual void completed(const std::vector<dpp::collected_reaction>& list) override {
if (list.size()) {
owner->message_create(dpp::message(list[0].react_channel->id, "I collected " + std::to_string(list.size()) + " reactions!"));
} else {
owner->message_create(dpp::message("... I got nothin'."));
}
}
};
int main() {
/* Create bot */
dpp::cluster bot("token", dpp::i_default_intents | dpp::i_message_content);
/* Pointer to reaction collector */
react_collector* r = nullptr;
bot.on_log(dpp::utility::cout_logger());
/* Message handler */
bot.on_message_create([&r, &bot](const dpp::message_create_t& event) {
/* If someone sends a message that has the text 'collect reactions!' start a reaction collector */
if (event.msg.content == "collect reactions!" && r == nullptr) {
/* Create a new reaction collector to collect reactions */
r = new react_collector(&bot, event.msg.id);
}
});
/* Start bot */
bot.start(dpp::st_wait);
return 0;
}

View File

@@ -0,0 +1,53 @@
#include <dpp/dpp.h>
int main() {
/* If your bot only uses the "/" prefix, you can remove the intents here. */
dpp::cluster bot("token", dpp::i_default_intents | dpp::i_message_content);
bot.on_log(dpp::utility::cout_logger());
/* Create command handler, and specify prefixes */
dpp::commandhandler command_handler(&bot);
/* Specifying a prefix of "/" tells the command handler it should also expect slash commands. Remove the .add_prefix(".") if you wish to only make it a slash command */
command_handler.add_prefix(".")
.add_prefix("/");
bot.on_ready([&command_handler](const dpp::ready_t &event) {
command_handler.add_command(
/* Command name */
"ping",
/* Parameters */
{
{"testparameter", dpp::param_info(dpp::pt_string, true, "Optional test parameter") }
},
/* Command handler */
[&command_handler](const std::string& command, const dpp::parameter_list_t& parameters, dpp::command_source src) {
std::string got_param;
if (!parameters.empty()) {
got_param = std::get<std::string>(parameters[0].second);
}
command_handler.reply(dpp::message("Pong! -> " + got_param), src);
},
/* Command description */
"A test ping command",
/* Guild id (omit for a guild command) */
819556414099554344
);
/* NOTE: We must call this to ensure slash commands are registered.
* This does a bulk register, which will replace other commands
* that are registered already!
*/
command_handler.register_commands();
});
bot.start(dpp::st_wait);
return 0;
}

View File

@@ -0,0 +1,53 @@
#include <dpp/dpp.h>
#include <dpp/unicode_emoji.h>
int main() {
dpp::cluster bot("token");
bot.on_log(dpp::utility::cout_logger());
/* The event is fired when someone issues your commands */
bot.on_slashcommand([&bot](const dpp::slashcommand_t& event) {
/* Check which command they ran */
if (event.command.get_command_name() == "button") {
/* Create a message */
dpp::message msg(event.command.channel_id, "this text has a button");
/* Add an action row, and then a button within the action row. */
msg.add_component(
dpp::component().add_component(
dpp::component()
.set_label("Click me!")
.set_type(dpp::cot_button)
.set_emoji(dpp::unicode_emoji::smile)
.set_style(dpp::cos_danger)
.set_id("myid")
)
);
/* Reply to the user with our message. */
event.reply(msg);
}
});
/* When a user clicks your button, the on_button_click event will fire,
* containing the custom_id you defined in your button.
*/
bot.on_button_click([&bot](const dpp::button_click_t& event) {
/* Button clicks are still interactions, and must be replied to in some form to
* prevent the "this interaction has failed" message from Discord to the user.
*/
event.reply("You clicked: " + event.custom_id);
});
bot.on_ready([&bot](const dpp::ready_t& event) {
if (dpp::run_once<struct register_bot_commands>()) {
/* Create and register a command when the bot is ready */
bot.global_command_create(dpp::slashcommand("button", "Send a message with a button!", bot.me.id));
}
});
bot.start(dpp::st_wait);
return 0;
}

View File

@@ -0,0 +1,61 @@
#include <dpp/dpp.h>
int main() {
dpp::cluster bot("token");
bot.on_log(dpp::utility::cout_logger());
/* The event is fired when someone issues your commands */
bot.on_slashcommand([&bot](const dpp::slashcommand_t& event) {
/* Check which command they ran */
if (event.command.get_command_name() == "math") {
/* Create a message */
dpp::message msg(event.command.channel_id, "What is 5+5?");
/* Add an action row, and then 3 buttons within the action row. */
msg.add_component(
dpp::component().add_component(
dpp::component()
.set_label("9")
.set_style(dpp::cos_primary)
.set_id("9")
)
.add_component(
dpp::component()
.set_label("10")
.set_style(dpp::cos_primary)
.set_id("10")
)
.add_component(
dpp::component()
.set_label("11")
.set_style(dpp::cos_primary)
.set_id("11")
)
);
/* Reply to the user with our message. */
event.reply(msg);
}
});
bot.on_button_click([&bot](const dpp::button_click_t & event) {
if (event.custom_id == "10") {
event.reply(dpp::message("You got it right!").set_flags(dpp::m_ephemeral));
} else {
event.reply(dpp::message("Wrong! Try again.").set_flags(dpp::m_ephemeral));
}
});
bot.on_ready([&bot](const dpp::ready_t& event) {
if (dpp::run_once<struct register_bot_commands>()) {
/* Create and register a command when the bot is ready */
bot.global_command_create(dpp::slashcommand("math", "A quick maths question!", bot.me.id));
}
});
bot.start(dpp::st_wait);
return 0;
}

View File

@@ -0,0 +1,53 @@
#include <dpp/dpp.h>
#include <dpp/unicode_emoji.h>
int main() {
dpp::cluster bot("token");
bot.on_log(dpp::utility::cout_logger());
/* The event is fired when someone issues your commands */
bot.on_slashcommand([&bot](const dpp::slashcommand_t& event) {
/* Check which command they ran */
if (event.command.get_command_name() == "select") {
/* Create a message */
dpp::message msg(event.command.channel_id, "This text has a select menu!");
/* Add an action row, and a select menu within the action row. */
msg.add_component(
dpp::component().add_component(
dpp::component()
.set_type(dpp::cot_selectmenu)
.set_placeholder("Pick something")
.add_select_option(dpp::select_option("label1","value1","description1").set_emoji(dpp::unicode_emoji::smile))
.add_select_option(dpp::select_option("label2","value2","description2").set_emoji(dpp::unicode_emoji::slight_smile))
.set_id("myselectid")
)
);
/* Reply to the user with our message. */
event.reply(msg);
}
});
/* When a user clicks your select menu , the on_select_click event will fire,
* containing the custom_id you defined in your select menu.
*/
bot.on_select_click([&bot](const dpp::select_click_t & event) {
/* Select clicks are still interactions, and must be replied to in some form to
* prevent the "this interaction has failed" message from Discord to the user.
*/
event.reply("You clicked " + event.custom_id + " and chose: " + event.values[0]);
});
bot.on_ready([&bot](const dpp::ready_t& event) {
if (dpp::run_once<struct register_bot_commands>()) {
/* Create and register a command when the bot is ready */
bot.global_command_create(dpp::slashcommand("select", "Select something at random!", bot.me.id));
}
});
bot.start(dpp::st_wait);
return 0;
}

View File

@@ -0,0 +1,46 @@
#include <dpp/dpp.h>
int main() {
dpp::cluster bot("token");
bot.on_log(dpp::utility::cout_logger());
/* The event is fired when someone issues your commands */
bot.on_slashcommand([&bot](const dpp::slashcommand_t& event) {
/* Check which command they ran */
if (event.command.get_command_name() == "select") {
/* Create a message */
dpp::message msg(event.command.channel_id, "This text has a select menu!");
/* Add an action row, and a select menu within the action row.
*
* By default, max values is 1, meaning people can only pick 1 option.
* We're changing this to two, so people can select multiple options!
* We'll also set the min_values to 2 so people have to pick another value!
*/
msg.add_component(
dpp::component().add_component(
dpp::component()
.set_type(dpp::cot_role_selectmenu)
.set_min_values(2)
.set_max_values(2)
.set_id("myselectid")
)
);
/* Reply to the user with our message. */
event.reply(msg);
}
});
bot.on_ready([&bot](const dpp::ready_t& event) {
if (dpp::run_once<struct register_bot_commands>()) {
/* Create and register a command when the bot is ready */
bot.global_command_create(dpp::slashcommand("select", "Select something at random!", bot.me.id));
}
});
bot.start(dpp::st_wait);
return 0;
}

View File

@@ -0,0 +1,38 @@
#include <dpp/dpp.h>
#include <iostream>
int main()
{
dpp::cluster bot("token");
bot.on_log(dpp::utility::cout_logger());
/* Use the on_user_context_menu event to look for user context menu actions */
bot.on_user_context_menu([](const dpp::user_context_menu_t& event) {
/* check if the context menu name is High Five */
if (event.command.get_command_name() == "high five") {
dpp::user user = event.get_user(); // the user who the command has been issued on
dpp::user author = event.command.get_issuing_user(); // the user who clicked on the context menu
event.reply(author.get_mention() + " slapped " + user.get_mention());
}
});
bot.on_ready([&bot](const dpp::ready_t &event) {
if (dpp::run_once<struct register_bot_commands>()) {
/* Create the command */
dpp::slashcommand command;
command.set_name("High Five")
.set_application_id(bot.me.id)
.set_type(dpp::ctxm_user);
/* Register the command */
bot.guild_command_create(command, 857692897221033129); /* Replace this with the guild id you want */
}
});
/* Start bot */
bot.start(dpp::st_wait);
return 0;
}

View File

@@ -0,0 +1,46 @@
#include <dpp/dpp.h>
int main() {
dpp::cluster bot{"token"};
bot.on_log(dpp::utility::cout_logger());
bot.on_slashcommand([](const dpp::slashcommand_t& event) -> dpp::task<void> {
if (event.command.get_command_name() == "test") {
// Make a message and add a button with its custom ID set to the command interaction's ID so we can identify it
dpp::message m{"Test"};
std::string id{event.command.id.str()};
m.add_component(
dpp::component{}.add_component(
dpp::component{}
.set_type(dpp::cot_button)
.set_label("Click me!")
.set_id(id)
)
);
co_await event.co_reply(m);
dpp::button_click_t click_event = co_await event.from->creator->on_button_click.when(
// Note!! Due to a bug in g++11 and g++12, id must be captured as a reference here or the compiler will destroy it twice. This is fixed in g++13
[&id] (dpp::button_click_t const &b) {
return b.custom_id == id;
}
);
// Acknowledge the click and edit the original response, removing the button
click_event.reply();
event.edit_original_response(dpp::message{"You clicked the button!"});
}
});
bot.on_ready([&bot](const dpp::ready_t& event) {
if (dpp::run_once<struct register_bot_commands>()) {
dpp::slashcommand command{"test", "Test awaiting for an event", bot.me.id};
bot.global_command_create(command);
}
});
bot.start(dpp::st_wait);
return 0;
}

View File

@@ -0,0 +1,52 @@
#include <dpp/dpp.h>
int main() {
dpp::cluster bot{"token"};
bot.on_log(dpp::utility::cout_logger());
bot.on_slashcommand([](const dpp::slashcommand_t& event) -> dpp::task<void> {
if (event.command.get_command_name() == "test") {
// Make a message and add a button with its custom ID set to the command interaction's ID so we can identify it
dpp::message m{"Test"};
std::string id{event.command.id.str()};
m.add_component(
dpp::component{}.add_component(
dpp::component{}
.set_type(dpp::cot_button)
.set_label("Click me!")
.set_id(id)
)
);
co_await event.co_reply(m);
auto result = co_await dpp::when_any{ // Whichever completes first...
event.from->creator->on_button_click.when([&id](const dpp::button_click_t &b) { // Button clicked
return b.custom_id == id;
}),
event.from->creator->co_sleep(5) // Or sleep 5 seconds
};
// Note!! Due to a bug in g++11 and g++12, id must be captured as a reference above or the compiler will destroy it twice. This is fixed in g++13
if (result.index() == 0) { // Awaitable #0 completed first, that is the button click event
// Acknowledge the click and edit the original response, removing the button
const dpp::button_click_t &click_event = result.get<0>();
click_event.reply();
event.edit_original_response(dpp::message{"You clicked the button with the id " + click_event.custom_id});
} else { // Here index() is 1, the timer expired
event.edit_original_response(dpp::message{"I haven't got all day!"});
}
}
});
bot.on_ready([&bot](const dpp::ready_t& event) {
if (dpp::run_once<struct register_bot_commands>()) {
dpp::slashcommand command{"test", "Test awaiting for an event", bot.me.id};
bot.global_command_create(command);
}
});
bot.start(dpp::st_wait);
return 0;
}

View File

@@ -0,0 +1,35 @@
#include <dpp/dpp.h>
int main() {
dpp::cluster bot{"token"};
bot.on_log(dpp::utility::cout_logger());
/* The event is fired when someone issues your commands */
bot.on_slashcommand([](const dpp::slashcommand_t& event) -> dpp::task<void> {
if (event.command.get_command_name() == "file") {
/* Request the image from the URL specified and co_await the response */
dpp::http_request_completion_t result = co_await event.from->creator->co_request("https://dpp.dev/DPP-Logo.png", dpp::m_get);
/* Create a message and attach the image on success */
dpp::message msg(event.command.channel_id, "This is my new attachment:");
if (result.status == 200) {
msg.add_file("logo.png", result.body);
}
/* Send the message, with our attachment. */
event.reply(msg);
}
});
bot.on_ready([&bot](const dpp::ready_t& event) {
if (dpp::run_once<struct register_bot_commands>()) {
/* Create and register a command when the bot is ready */
bot.global_command_create(dpp::slashcommand{"file", "Send a message with an image attached from the internet!", bot.me.id});
}
});
bot.start(dpp::st_wait);
return 0;
}

View File

@@ -0,0 +1,65 @@
#include <dpp/dpp.h>
int main() {
dpp::cluster bot{"token"};
bot.on_log(dpp::utility::cout_logger());
bot.on_slashcommand([](const dpp::slashcommand_t& event) -> dpp::task<void> {
if (event.command.get_command_name() == "addemoji") {
dpp::cluster *cluster = event.from->creator;
// Retrieve parameter values
dpp::snowflake file_id = std::get<dpp::snowflake>(event.get_parameter("file"));
std::string emoji_name = std::get<std::string>(event.get_parameter("name"));
// Get the attachment from the resolved list
const dpp::attachment &attachment = event.command.get_resolved_attachment(file_id);
// For simplicity for this example we only support PNG
if (attachment.content_type != "image/png") {
// While we could use event.co_reply, we can just use event.reply, as we will exit the command anyway and don't need to wait on the result
event.reply("Error: type " + attachment.content_type + " not supported");
co_return;
}
// Send a "<bot> is thinking..." message, to wait on later so we can edit
dpp::async thinking = event.co_thinking(false);
// Download and co_await the result
dpp::http_request_completion_t response = co_await cluster->co_request(attachment.url, dpp::m_get);
if (response.status != 200) { // Page didn't send the image
co_await thinking; // Wait for the thinking response to arrive so we can edit
event.edit_response("Error: could not download the attachment");
} else {
// Load the image data in a dpp::emoji
dpp::emoji emoji(emoji_name);
emoji.load_image(response.body, dpp::image_type::i_png);
// Create the emoji and co_await the response
dpp::confirmation_callback_t confirmation = co_await cluster->co_guild_emoji_create(event.command.guild_id, emoji);
co_await thinking; // Wait for the thinking response to arrive so we can edit
if (confirmation.is_error()) {
event.edit_response("Error: could not add emoji: " + confirmation.get_error().message);
} else { // Success
event.edit_response("Successfully added " + confirmation.get<dpp::emoji>().get_mention()); // Show the new emoji
}
}
}
});
bot.on_ready([&bot](const dpp::ready_t& event) {
if (dpp::run_once<struct register_bot_commands>()) {
dpp::slashcommand command("addemoji", "Add an emoji", bot.me.id);
// Add file and name as required parameters
command.add_option(dpp::command_option(dpp::co_attachment, "file", "Select an image", true));
command.add_option(dpp::command_option(dpp::co_string, "name", "Name of the emoji to add", true));
bot.global_command_create(command);
}
});
bot.start(dpp::st_wait);
return 0;
}

View File

@@ -0,0 +1,85 @@
#include <dpp/dpp.h>
int main() {
dpp::cluster bot{"token"};
bot.on_log(dpp::utility::cout_logger());
bot.on_slashcommand([](const dpp::slashcommand_t& event) -> dpp::task<void> {
if (event.command.get_command_name() == "avatar") {
// Make a nested coroutine to fetch the guild member requested, that returns it as an optional
constexpr auto resolve_member = [](const dpp::slashcommand_t &event) -> dpp::task<std::optional<dpp::guild_member>> {
const dpp::command_value &user_param = event.get_parameter("user");
dpp::snowflake user_id;
if (std::holds_alternative<std::monostate>(user_param)) {
user_id = event.command.usr.id; // Parameter is empty so user is sender
}
else if (std::holds_alternative<dpp::snowflake>(user_param)) {
user_id = std::get<dpp::snowflake>(user_param); // Parameter has a user
}
// If we have the guild member in the command's resolved data, return it
const auto &member_map = event.command.resolved.members;
if (auto member = member_map.find(user_id); member != member_map.end()) {
co_return member->second;
}
// Try looking in guild cache
dpp::guild *guild = dpp::find_guild(event.command.guild_id);
if (guild) {
// Look in guild's member cache
if (auto member = guild->members.find(user_id); member != guild->members.end()) {
co_return member->second;
}
}
// Finally if everything else failed, request API
dpp::confirmation_callback_t confirmation = co_await event.from->creator->co_guild_get_member(event.command.guild_id, user_id);
if (confirmation.is_error()) {
co_return std::nullopt; // Member not found, return empty
} else {
co_return confirmation.get<dpp::guild_member>();
}
};
// Send a "<bot> is thinking..." message, to wait on later so we can edit
dpp::async thinking = event.co_thinking(false);
// Call our coroutine defined above to retrieve the member requested
std::optional<dpp::guild_member> member = co_await resolve_member(event);
if (!member.has_value()) {
// Wait for the thinking response to arrive to make sure we can edit
co_await thinking;
event.edit_original_response(dpp::message{"User not found in this server!"});
co_return;
}
std::string avatar_url = member->get_avatar_url(512);
if (avatar_url.empty()) { // Member does not have a custom avatar for this server, get their user avatar
dpp::confirmation_callback_t confirmation = co_await event.from->creator->co_user_get_cached(member->user_id);
if (confirmation.is_error()) {
// Wait for the thinking response to arrive to make sure we can edit
co_await thinking;
event.edit_original_response(dpp::message{"User not found!"});
co_return;
}
avatar_url = confirmation.get<dpp::user_identified>().get_avatar_url(512);
}
// Wait for the thinking response to arrive to make sure we can edit
co_await thinking;
event.edit_original_response(dpp::message{avatar_url});
}
});
bot.on_ready([&bot](const dpp::ready_t& event) {
if (dpp::run_once<struct register_bot_commands>()) {
dpp::slashcommand command("avatar", "Get your or another user's avatar image", bot.me.id);
command.add_option(dpp::command_option(dpp::co_user, "user", "User to fetch the avatar from"));
bot.global_command_create(command);
}
});
bot.start(dpp::st_wait);
return 0;
}

View File

@@ -0,0 +1,47 @@
#include <dpp/dpp.h>
#include <dpp/unicode_emoji.h>
int main() {
dpp::cluster bot("token");
bot.on_log(dpp::utility::cout_logger());
/* The event is fired when someone issues your commands */
bot.on_slashcommand([&bot](const dpp::slashcommand_t& event) {
/* Check which command they ran */
if (event.command.get_command_name() == "select") {
/* Create a message */
dpp::message msg(event.command.channel_id, "This text has a select menu!");
/* Add an action row, and a select menu within the action row.
*
* Your default values are limited to max_values,
* meaning you can't add more default values than the allowed max values.
*/
msg.add_component(
dpp::component().add_component(
dpp::component()
.set_type(dpp::cot_role_selectmenu)
.set_min_values(2)
.set_max_values(2)
.add_default_value(dpp::snowflake{667756886443163648}, dpp::cdt_role)
.set_id("myselectid")
)
);
/* Reply to the user with our message. */
event.reply(msg);
}
});
bot.on_ready([&bot](const dpp::ready_t& event) {
if (dpp::run_once<struct register_bot_commands>()) {
/* Create and register a command when the bot is ready */
bot.global_command_create(dpp::slashcommand("select", "Select something at random!", bot.me.id));
}
});
bot.start(dpp::st_wait);
return 0;
}

View File

@@ -0,0 +1,22 @@
#include <dpp/dpp.h>
int main() {
/* Create the bot, but with our intents so we can use messages. */
dpp::cluster bot("token", dpp::i_default_intents | dpp::i_message_content);
bot.on_log(dpp::utility::cout_logger());
/* The event is fired when the bot detects a message in any server and any channel it has access to. */
bot.on_message_create([&bot](const dpp::message_create_t& event) {
/* See if the message contains the phrase we want to check for.
* If there's at least a single match, we reply and say it's not allowed.
*/
if (event.msg.content.find("bad word") != std::string::npos) {
event.reply("That is not allowed here. Please, mind your language!", true);
}
});
bot.start(dpp::st_wait);
return 0;
}

View File

@@ -0,0 +1,77 @@
#include <dpp/dpp.h>
int main() {
dpp::cluster bot("token", dpp::i_default_intents | dpp::i_message_content);
/* the second argument is a bitmask of intents - i_message_content is needed to get messages */
bot.on_log(dpp::utility::cout_logger());
/* The event is fired when someone issues your commands */
bot.on_slashcommand([&bot](const dpp::slashcommand_t& event) {
if (event.command.get_command_name() == "msg-send") {
event.reply("That's a message");
} else if (event.command.get_command_name() == "msg-edit") {
const auto content = std::get<std::string>(event.get_parameter("content"));
/* get message to edit it after */
const dpp::snowflake msg_id = std::get<std::string>(event.get_parameter("msg-id"));
/* here string will automatically be converted to snowflake */
bot.message_get(msg_id, event.command.channel_id, [&bot, content, event](const dpp::confirmation_callback_t& callback) {
if (callback.is_error()) {
event.reply("error");
return;
}
auto message = callback.get<dpp::message>();
/* change the message content and edit the message itself */
message.set_content(content);
bot.message_edit(message);
event.reply("Message content is now `" + content + "`.");
});
} else if (event.command.get_command_name() == "channel-edit") {
const auto name = std::get<std::string>(event.get_parameter("name"));
/* get the channel to edit it after */
const auto channel_id = std::get<dpp::snowflake>(event.get_parameter("channel"));
bot.channel_get(channel_id, [&bot, name, event](const dpp::confirmation_callback_t& callback) {
if (callback.is_error()) {
event.reply("error");
return;
}
auto channel = callback.get<dpp::channel>();
/* change the channel name and edit the channel itself */
channel.set_name(name);
bot.channel_edit(channel);
event.reply("Channel name is now `" + name + "`.");
});
}
});
bot.on_ready([&bot](const dpp::ready_t& event) {
if (dpp::run_once <struct register_global_commands>()) {
dpp::slashcommand msg_edit("msg-edit", "Edit a message sent by the bot", bot.me.id);
msg_edit.add_option(dpp::command_option(dpp::co_string, "msg-id", "ID of the message to edit", true)); /* true for required option */
msg_edit.add_option(dpp::command_option(dpp::co_string, "content", "New content for the message", true)); /* same here */
dpp::slashcommand channel_edit("channel-edit", "Edit the name of channel specified", bot.me.id);
channel_edit.add_option(dpp::command_option(dpp::co_channel, "channel", "Channel to edit", true));
channel_edit.add_option(dpp::command_option(dpp::co_string, "name", "New name for the channel", true));
dpp::slashcommand msg_send("msg-send", "Send my message", bot.me.id);
bot.global_bulk_command_create({ msg_edit, channel_edit, msg_send });
}
});
bot.start(dpp::st_wait);
return 0;
}

View File

@@ -0,0 +1,59 @@
#include <dpp/dpp.h>
int main() {
/* Setup the bot */
dpp::cluster bot("token", dpp::i_default_intents | dpp::i_message_content);
/* The event is fired when someone issues your commands */
bot.on_slashcommand([&bot](const dpp::slashcommand_t& event) {
/* Check which command they ran */
if (event.command.get_command_name() == "embed") {
/* Create an embed */
dpp::embed embed = dpp::embed()
.set_color(dpp::colors::sti_blue)
.set_title("Some name")
.set_url("https://dpp.dev/")
.set_author("Some name", "https://dpp.dev/", "https://dpp.dev/DPP-Logo.png")
.set_description("Some description here")
.set_thumbnail("https://dpp.dev/DPP-Logo.png")
.add_field(
"Regular field title",
"Some value here"
)
.add_field(
"Inline field title",
"Some value here",
true
)
.add_field(
"Inline field title",
"Some value here",
true
)
.set_image("https://dpp.dev/DPP-Logo.png")
.set_footer(
dpp::embed_footer()
.set_text("Some footer text here")
.set_icon("https://dpp.dev/DPP-Logo.png")
)
.set_timestamp(time(0));
/* Create a message with the content as our new embed. */
dpp::message msg(event.command.channel_id, embed);
/* Reply to the user with the message, containing our embed. */
event.reply(msg);
}
});
bot.on_ready([&bot](const dpp::ready_t& event) {
if (dpp::run_once<struct register_bot_commands>()) {
/* Create and register a command when the bot is ready */
bot.global_command_create(dpp::slashcommand("embed", "Send a test embed!", bot.me.id));
}
});
bot.start(dpp::st_wait);
return 0;
}

View File

@@ -0,0 +1,28 @@
#include <dpp/dpp.h>
int main() {
/* Create the bot */
dpp::cluster bot("token");
bot.on_log(dpp::utility::cout_logger());
/* The event is fired when someone issues your commands */
bot.on_slashcommand([&bot](const dpp::slashcommand_t & event) {
/* Check which command they ran */
if (event.command.get_command_name() == "hello") {
/* Reply to the user, but only let them see the response. */
event.reply(dpp::message("Hello! How are you today?").set_flags(dpp::m_ephemeral));
}
});
bot.on_ready([&bot](const dpp::ready_t & event) {
if (dpp::run_once<struct register_bot_commands>()) {
/* Create and Register the command */
bot.global_command_create(dpp::slashcommand("hello", "Hello there!", bot.me.id));
}
});
bot.start(dpp::st_wait);
return 0;
}

View File

@@ -0,0 +1,175 @@
/**
* D++ eval command example.
* This is dangerous and for educational use only, here be dragons!
*/
#include <dpp/dpp.h>
#include <fmt/format.h>
#include <fstream>
#include <iostream>
/* We have to define this to make certain functions visible */
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <link.h>
#include <dlfcn.h>
#include "eval.h"
/* This is an example function you can expose to your eval command */
int test_function() {
return 42;
}
/* Important: This code is for UNIX-like systems only, e.g.
* Linux, BSD, OSX. It will NOT work on Windows!
* Note for OSX you'll probably have to change all references
* from .so to .dylib.
*/
int main() {
dpp::cluster bot("token", dpp::i_default_intents | dpp::i_message_content);
bot.on_log(dpp::utility::cout_logger());
/* This won't work in a slash command very well yet, as there is not yet
* a multi-line slash command input type.
*/
bot.on_message_create([&bot](const auto & event) {
if (dpp::utility::utf8substr(event.msg.content, 0, 5) == "!eval") {
/**
* THIS IS CRITICALLY IMPORTANT!
* Never EVER make an eval command that isn't restricted to a specific developer by user id.
* With access to this command the person who invokes it has at best full control over
* your bot's user account and at worst, full control over your entire network!!!
* Eval commands are Evil (pun intended) and could even be considered a security
* vulnerability. YOU HAVE BEEN WARNED!
*/
if (event.msg.author.id != dpp::snowflake(MY_DEVELOPER)) {
bot.message_create(dpp::message(event.msg.channel_id, "On the day i do this for you, Satan will be ice skating to work."));
return;
}
/* We start by creating a string that contains a cpp program for a simple library.
* The library will contain one exported function called so_exec() that is called
* containing the raw C++ code to eval.
*/
std::string code = "#include <iostream>\n\
#include <string>\n\
#include <map>\n\
#include <unordered_map>\n\
#include <stdint.h>\n\
#include <dpp/dpp.h>\n\
#include <dpp/nlohmann/json.hpp>\n\
#include <fmt/format.h>\n\
#include \"eval.h\"\n\
extern \"C\" void so_exec(dpp::cluster& bot, dpp::message_create_t event) {\n\
" + dpp::utility::utf8substr(
event.msg.content,
6,
dpp::utility::utf8len(event.msg.content)
) + ";\n\
return;\n\
}";
/* Next we output this string full of C++ to a cpp file on disk.
* This code assumes the current directory is writeable. The file will have a
* unique name made from the user's id and the message id.
*/
std::string source_filename = std::to_string(event.msg.author.id) + "_" + std::to_string(event.msg.id) + ".cpp";
std::fstream code_file(source_filename, std::fstream::binary | std::fstream::out);
if (!code_file.is_open()) {
bot.message_create(dpp::message(event.msg.channel_id, "Unable to create source file for `eval`"));
return;
}
code_file << code;
code_file.close();
/* Now to actually compile the file. We use dpp::utility::exec to
* invoke a compiler. This assumes you are using g++, and it is in your path.
*/
double compile_start = dpp::utility::time_f();
dpp::utility::exec("g++", {
"-std=c++17",
"-shared", /* Build the output as a .so file */
"-fPIC",
std::string("-o") + std::to_string(event.msg.author.id) + "_" + std::to_string(event.msg.id) + ".so",
std::to_string(event.msg.author.id) + "_" + std::to_string(event.msg.id) + ".cpp",
"-ldpp",
"-ldl"
}, [event, &bot, source_filename, compile_start](const std::string &output) {
/* After g++ is ran we end up inside this lambda with the output as a string */
double compile_time = dpp::utility::time_f() - compile_start;
/* Delete our cpp file, we don't need it any more */
std::string del_file = std::string(getenv("PWD")) + std::to_string(event.msg.author.id) + "_" + std::to_string(event.msg.id) + ".cpp";
unlink(del_file.c_str());
/* On successful compilation g++ outputs nothing, so any output here is error output */
if (output.length()) {
bot.message_create(dpp::message(event.msg.channel_id, "Compile error: ```\n" + output + "\n```"));
} else {
/* Now for the meat of the function. To actually load
* our shared object we use dlopen() to load it into the
* memory space of our bot. If dlopen() returns a nullptr,
* the shared object could not be loaded. The user probably
* did something odd with the symbols inside their eval.
*/
std::string dl = std::string(getenv("PWD")) + std::to_string(event.msg.author.id) + "_" + std::to_string(event.msg.id) + ".so";
auto shared_object_handle = dlopen(dl.c_str(), RTLD_NOW);
if (!shared_object_handle) {
const char *dlsym_error = dlerror();
bot.message_create(dpp::message(event.msg.channel_id, "Shared object load error: ```\n" +
std::string(dlsym_error ? dlsym_error : "Unknown error") +"\n```"));
return;
}
/* This type represents the "void so_exec()" function inside
* the shared object library file.
*/
using function_pointer = void(*)(dpp::cluster&, dpp::message_create_t);
/* Attempt to find the function called so_exec() inside the
* library we just loaded. If we can't find it, then the user
* did something really strange in their eval. Also note it's
* important we call dlerror() here to reset it before trying
* to use it a second time. It's weird-ass C code and is just
* like that.
*/
dlerror();
function_pointer exec_run = (function_pointer)dlsym(shared_object_handle, "so_exec");
const char *dlsym_error = dlerror();
if (dlsym_error) {
bot.message_create(dpp::message(event.msg.channel_id, "Shared object load error: ```\n" + std::string(dlsym_error) +"\n```"));
dlclose(shared_object_handle);
return;
}
/* Now we have a function pointer to our actual exec code in
* 'exec_run', so lets call it, and pass it a reference to
* the cluster, and also a copy of the message_create_t.
*/
double run_start = dpp::utility::time_f();
exec_run(bot, event);
double run_time = dpp::utility::time_f() - run_start;
/* When we're done with a .so file we must always dlclose() it */
dlclose(shared_object_handle);
/* We are now done with the compiled code too */
unlink(dl.c_str());
/* Output some statistics */
bot.message_create(dpp::message(event.msg.channel_id,
"Execution completed. Compile time: " + std::to_string(compile_time) +
"s, execution time " + std::to_string(run_time) + "s"));
}
});
}
});
bot.start(dpp::st_wait);
return 0;
}

View File

@@ -0,0 +1,14 @@
#pragma once
/* This is the snowflake ID of the bot's developer.
* The eval command will be restricted to this user.
*/
#define MY_DEVELOPER 189759562910400512ULL
/* Any functions you want to be usable from within an eval,
* that are not part of D++ itself or the message event, you
* can put here as forward declarations. The test_function()
* serves as an example.
*/
int test_function();

View File

@@ -0,0 +1,23 @@
#include <dpp/dpp.h>
const std::string BOT_TOKEN = "add your token here";
int main() {
dpp::cluster bot(BOT_TOKEN);
bot.on_log(dpp::utility::cout_logger());
bot.on_slashcommand([](const dpp::slashcommand_t& event) {
if (event.command.get_command_name() == "ping") {
event.reply("Pong!");
}
});
bot.on_ready([&bot](const dpp::ready_t& event) {
if (dpp::run_once<struct register_bot_commands>()) {
bot.global_command_create(dpp::slashcommand("ping", "Ping pong!", bot.me.id));
}
});
bot.start(dpp::st_wait);
}

View File

@@ -0,0 +1,4 @@
#include <dpp/dpp.h>
int main() {
}

View File

@@ -0,0 +1,7 @@
#include <dpp/dpp.h>
const std::string BOT_TOKEN = "add your token here";
int main() {
dpp::cluster bot(BOT_TOKEN);
}

View File

@@ -0,0 +1,13 @@
#include <dpp/dpp.h>
const std::string BOT_TOKEN = "add your token here";
int main() {
dpp::cluster bot(BOT_TOKEN);
bot.on_ready([&bot](const dpp::ready_t& event) {
if (dpp::run_once<struct register_bot_commands>()) {
bot.global_command_create(dpp::slashcommand("ping", "Ping pong!", bot.me.id));
}
});
}

View File

@@ -0,0 +1,16 @@
#include <dpp/dpp.h>
const std::string BOT_TOKEN = "add your token here";
int main() {
dpp::cluster bot(BOT_TOKEN);
bot.on_slashcommand([](const dpp::slashcommand_t& event) {
});
bot.on_ready([&bot](const dpp::ready_t& event) {
if (dpp::run_once<struct register_bot_commands>()) {
bot.global_command_create(dpp::slashcommand("ping", "Ping pong!", bot.me.id));
}
});
}

View File

@@ -0,0 +1,19 @@
#include <dpp/dpp.h>
const std::string BOT_TOKEN = "add your token here";
int main() {
dpp::cluster bot(BOT_TOKEN);
bot.on_slashcommand([](const dpp::slashcommand_t& event) {
if (event.command.get_command_name() == "ping") {
event.reply("Pong!");
}
});
bot.on_ready([&bot](const dpp::ready_t& event) {
if (dpp::run_once<struct register_bot_commands>()) {
bot.global_command_create(dpp::slashcommand("ping", "Ping pong!", bot.me.id));
}
});
}

View File

@@ -0,0 +1,23 @@
#include <dpp/dpp.h>
const std::string BOT_TOKEN = "add your token here";
int main() {
dpp::cluster bot(BOT_TOKEN);
bot.on_log(dpp::utility::cout_logger());
bot.on_slashcommand([](const dpp::slashcommand_t& event) {
if (event.command.get_command_name() == "ping") {
event.reply("Pong!");
}
});
bot.on_ready([&bot](const dpp::ready_t& event) {
if (dpp::run_once<struct register_bot_commands>()) {
bot.global_command_create(dpp::slashcommand("ping", "Ping pong!", bot.me.id));
}
});
bot.start(dpp::st_wait);
}

View File

@@ -0,0 +1,30 @@
#include <dpp/dpp.h>
#include <iostream>
int main() {
dpp::cluster bot("token");
bot.on_log(dpp::utility::cout_logger());
bot.on_ready([&bot](const dpp::ready_t& event) {
// Arbitrary post data as a string
std::string mypostdata = "{\"value\": 42}";
// Make a HTTP POST request. HTTP and HTTPS are supported here.
bot.request(
"http://www.somebotlist.com/api/servers", dpp::m_post, [](const dpp::http_request_completion_t & cc) {
// This callback is called when the HTTP request completes. See documentation of
// dpp::http_request_completion_t for information on the fields in the parameter.
std::cout << "I got reply: " << cc.body << " with HTTP status code: " << cc.status << "\n";
},
mypostdata,
"application/json",
{
{"Authorization", "Bearer tokengoeshere"}
}
);
});
bot.start(dpp::st_wait);
return 0;
}

View File

@@ -0,0 +1,85 @@
#include <dpp/dpp.h>
#include <iomanip>
#include <sstream>
int main() {
/* Setup the bot */
dpp::cluster bot("token");
bot.on_log(dpp::utility::cout_logger());
/* The event is fired when someone issues your commands */
bot.on_slashcommand([&bot](const dpp::slashcommand_t& event) {
/* Check which command they ran */
if (event.command.get_command_name() == "join") {
/* Get the guild */
dpp::guild* g = dpp::find_guild(event.command.guild_id);
/* Get the voice channel that the bot is currently in from this server (will return nullptr if we're not in a voice channel!) */
auto current_vc = event.from->get_voice(event.command.guild_id);
bool join_vc = true;
/* Are we in a voice channel? If so, let's see if we're in the right channel. */
if (current_vc) {
/* Find the channel id that the user is currently in */
auto users_vc = g->voice_members.find(event.command.get_issuing_user().id);
if (users_vc != g->voice_members.end() && current_vc->channel_id == users_vc->second.channel_id) {
join_vc = false;
/* We are on this voice channel, at this point we can send any audio instantly to vc:
* current_vc->send_audio_raw(...)
*/
} else {
/* We are on a different voice channel. We should leave it, then join the new one
* by falling through to the join_vc branch below.
*/
event.from->disconnect_voice(event.command.guild_id);
join_vc = true;
}
}
/* If we need to join a vc at all, join it here if join_vc == true */
if (join_vc) {
/* Attempt to connect to a voice channel, returns false if we fail to connect. */
/* The user issuing the command is not on any voice channel, we can't do anything */
if (!g->connect_member_voice(event.command.get_issuing_user().id)) {
event.reply("You don't seem to be in a voice channel!");
return;
}
/* We are now connecting to a vc. Wait for on_voice_ready
* event, and then send the audio within that event:
*
* event.voice_client->send_audio_raw(...);
*
* NOTE: We can't instantly send audio, as we have to wait for
* the connection to the voice server to be established!
*/
/* Tell the user we joined their channel. */
event.reply("Joined your channel!");
} else {
event.reply("Don't need to join your channel as i'm already there with you!");
}
}
});
bot.on_ready([&bot](const dpp::ready_t & event) {
if (dpp::run_once<struct register_bot_commands>()) {
/* Create a new command. */
bot.global_command_create(dpp::slashcommand("join", "Joins your voice channel.", bot.me.id));
}
});
/* Start bot */
bot.start(dpp::st_wait);
return 0;
}

View File

@@ -0,0 +1,35 @@
#include <dpp/dpp.h>
int main() {
/* Create the bot */
dpp::cluster bot("token");
bot.on_log(dpp::utility::cout_logger());
/* The event is fired when the bot detects a message in any server and any channel it has access to. */
bot.on_slashcommand([&bot](const dpp::slashcommand_t& event) {
/* Check which command they ran */
if (event.command.get_command_name() == "create-thread") {
/* Here we create a thread in the current channel. It will expire after 60 minutes of inactivity. We'll also allow other mods to join, and we won't add a slowdown timer. */
bot.thread_create("Cool thread!", event.command.channel_id, 60, dpp::channel_type::CHANNEL_PUBLIC_THREAD, true, 0, [event](const dpp::confirmation_callback_t& callback) {
if (callback.is_error()) {
event.reply("Failed to create a thread!");
return;
}
event.reply("Created a thread for you!");
});
}
});
bot.on_ready([&bot](const dpp::ready_t& event) {
if (dpp::run_once<struct register_bot_commands>()) {
/* Create and register the command */
bot.global_command_create(dpp::slashcommand("create-thread", "Create a thread!", bot.me.id));
}
});
bot.start(dpp::st_wait);
return 0;
}

View File

@@ -0,0 +1,56 @@
#include <dpp/dpp.h>
int main() {
/* Create the bot */
dpp::cluster bot("token");
bot.on_log(dpp::utility::cout_logger());
/* The event is fired when the bot detects a message in any server and any channel it has access to. */
bot.on_slashcommand([&bot](const dpp::slashcommand_t & event) {
/* Check which command they ran */
if (event.command.get_command_name() == "message-thread") {
/* Get all active threads in a guild. */
bot.threads_get_active(event.command.guild_id, [&bot, event](const dpp::confirmation_callback_t& callback) {
if (callback.is_error()) {
event.reply("Failed to get threads!");
return;
}
/* Get the list of active threads in the guild. */
auto threads = callback.get<dpp::active_threads>();
dpp::snowflake thread_id;
/* Loop through the threads, getting each value in the map. Then we get the first value and then break off.
* The reason we're getting only the first value is because, for this example, we'll just assume you've only got a single active thread (the one created by the bot)
*/
for (const auto& _thread : threads) {
thread_id = _thread.first;
break;
}
/* Send a message in the first thread we find. */
bot.message_create(dpp::message(thread_id, "Hey, I'm first to message in a cool thread!"), [event](const dpp::confirmation_callback_t& callback2) {
if (callback2.is_error()) {
event.reply("Failed to send a message in a thread.");
return;
}
event.reply("I've sent a message in the specified thread.");
});
});
}
});
bot.on_ready([&bot](const dpp::ready_t& event) {
if (dpp::run_once<struct register_bot_commands>()) {
/* Create and register the command */
bot.global_command_create(dpp::slashcommand("message-thread", "Message a thread!", bot.me.id));
}
});
bot.start(dpp::st_wait);
return 0;
}

View File

@@ -0,0 +1,49 @@
#include <dpp/dpp.h>
int main() {
/* Create the bot */
dpp::cluster bot("token");
bot.on_log(dpp::utility::cout_logger());
/* The event is fired when the bot detects a message in any server and any channel it has access to. */
bot.on_slashcommand([&bot](const dpp::slashcommand_t& event) {
/* Check which command they ran */
if (event.command.get_command_name() == "lock-thread") {
/* Get this channel as a thread. */
bot.thread_get(event.command.channel_id, [&bot, event](const dpp::confirmation_callback_t& callback) {
if (callback.is_error()) {
event.reply("I failed to get the thread!");
return;
}
/* Get the thread from the callback. */
auto thread = callback.get<dpp::thread>();
/* Set the thread to locked. */
thread.metadata.locked = true;
/* Now we tell discord about our updates, meaning the thread will lock! */
bot.thread_edit(thread, [event](const dpp::confirmation_callback_t& callback2) {
if (callback2.is_error()) {
event.reply("I failed to lock the thread!");
return;
}
event.reply("I have locked the thread!");
});
});
}
});
bot.on_ready([&bot](const dpp::ready_t& event) {
if (dpp::run_once<struct register_bot_commands>()) {
/* Create and register the command */
bot.global_command_create(dpp::slashcommand("lock-thread", "Lock the thread that you run this command in!", bot.me.id));
}
});
bot.start(dpp::st_wait);
return 0;
}

View File

@@ -0,0 +1,70 @@
#include <dpp/dpp.h>
#include <iostream>
int main() {
dpp::cluster bot("token");
bot.on_log(dpp::utility::cout_logger());
bot.on_slashcommand([&bot](const dpp::slashcommand_t& event) {
/* Check for our /dialog command */
if (event.command.get_command_name() == "dialog") {
/* Instantiate an interaction_modal_response object */
dpp::interaction_modal_response modal("my_modal", "Please enter stuff");
/* Add a text component */
modal.add_component(
dpp::component()
.set_label("Short type rammel")
.set_id("field_id")
.set_type(dpp::cot_text)
.set_placeholder("gumd")
.set_min_length(5)
.set_max_length(50)
.set_text_style(dpp::text_short)
);
/* Add another text component in the next row, as required by Discord */
modal.add_row();
modal.add_component(
dpp::component()
.set_label("Type rammel")
.set_id("field_id2")
.set_type(dpp::cot_text)
.set_placeholder("gumf")
.set_min_length(1)
.set_max_length(2000)
.set_text_style(dpp::text_paragraph)
);
/* Trigger the dialog box. All dialog boxes are ephemeral */
event.dialog(modal);
}
});
/* This event handles form submission for the modal dialog we create above */
bot.on_form_submit([](const dpp::form_submit_t & event) {
/* For this simple example, we know the first element of the first row ([0][0]) is value type string.
* In the real world, it may not be safe to make such assumptions!
*/
std::string v = std::get<std::string>(event.components[0].components[0].value);
dpp::message m;
m.set_content("You entered: " + v).set_flags(dpp::m_ephemeral);
/* Emit a reply. Form submission is still an interaction and must generate some form of reply! */
event.reply(m);
});
bot.on_ready([&bot](const dpp::ready_t & event) {
if (dpp::run_once<struct register_bot_commands>()) {
/* Create a slash command and register it as a global command */
bot.global_command_create(dpp::slashcommand("dialog", "Make a modal dialog box", bot.me.id));
}
});
/* Start bot */
bot.start(dpp::st_wait);
return 0;
}

View File

@@ -0,0 +1,111 @@
#include <dpp/dpp.h>
#include <fmt/format.h>
#include <iomanip>
#include <sstream>
#include <vector>
#include <fstream>
#include <iostream>
#include <mpg123.h>
#include <out123.h>
/* For an example we will hardcode a path to some awesome music here */
#define MUSIC_FILE "/media/music/Rick Astley/Whenever You Need Somebody/Never Gonna Give You Up.mp3"
int main() {
/* This will hold the decoded MP3.
* The D++ library expects PCM format, which are raw sound
* data, 2 channel stereo, 16 bit signed 48000Hz.
*/
std::vector<uint8_t> pcmdata;
mpg123_init();
int err = 0;
unsigned char* buffer;
size_t buffer_size, done;
int channels, encoding;
long rate;
/* Note it is important to force the frequency to 48000 for Discord compatibility */
mpg123_handle *mh = mpg123_new(NULL, &err);
mpg123_param(mh, MPG123_FORCE_RATE, 48000, 48000.0);
/* Decode entire file into a vector. You could do this on the fly, but if you do that
* you may get timing issues if your CPU is busy at the time and you are streaming to
* a lot of channels/guilds.
*/
buffer_size = mpg123_outblock(mh);
buffer = new unsigned char[buffer_size];
/* Note: In a real world bot, this should have some error logging */
mpg123_open(mh, MUSIC_FILE);
mpg123_getformat(mh, &rate, &channels, &encoding);
unsigned int counter = 0;
for (int totalBytes = 0; mpg123_read(mh, buffer, buffer_size, &done) == MPG123_OK; ) {
for (size_t i = 0; i < buffer_size; i++) {
pcmdata.push_back(buffer[i]);
}
counter += buffer_size;
totalBytes += done;
}
delete[] buffer;
mpg123_close(mh);
mpg123_delete(mh);
/* Setup the bot */
dpp::cluster bot("token");
bot.on_log(dpp::utility::cout_logger());
/* The event is fired when someone issues your commands */
bot.on_slashcommand([&bot, &pcmdata](const dpp::slashcommand_t& event) {
/* Check which command they ran */
if (event.command.get_command_name() == "join") {
/* Get the guild */
dpp::guild* g = dpp::find_guild(event.command.guild_id);
/* Attempt to connect to a voice channel, returns false if we fail to connect. */
if (!g->connect_member_voice(event.command.get_issuing_user().id)) {
event.reply("You don't seem to be in a voice channel!");
return;
}
/* Tell the user we joined their channel. */
event.reply("Joined your channel!");
} else if (event.command.get_command_name() == "mp3") {
/* Get the voice channel the bot is in, in this current guild. */
dpp::voiceconn* v = event.from->get_voice(event.command.guild_id);
/* If the voice channel was invalid, or there is an issue with it, then tell the user. */
if (!v || !v->voiceclient || !v->voiceclient->is_ready()) {
event.reply("There was an issue with getting the voice channel. Make sure I'm in a voice channel!");
return;
}
/* Stream the already decoded MP3 file. This passes the PCM data to the library to be encoded to OPUS */
v->voiceclient->send_audio_raw((uint16_t*)pcmdata.data(), pcmdata.size());
event.reply("Played the mp3 file.");
}
});
bot.on_ready([&bot](const dpp::ready_t & event) {
if (dpp::run_once<struct register_bot_commands>()) {
/* Create a new command. */
dpp::slashcommand joincommand("join", "Joins your voice channel.", bot.me.id);
dpp::slashcommand mp3command("mp3", "Plays an mp3 file.", bot.me.id);
bot.global_bulk_command_create({ joincommand, mp3command });
}
});
/* Start bot */
bot.start(dpp::st_wait);
/* Clean up */
mpg123_exit();
return 0;
}

View File

@@ -0,0 +1,172 @@
#include <dpp/dpp.h>
#include <iomanip>
#include <sstream>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ogg/ogg.h>
#include <opus/opusfile.h>
int main(int argc, char const *argv[]) {
/* Load an ogg opus file into memory.
* The bot expects opus packets to be 2 channel stereo, 48000Hz.
*
* You may use ffmpeg to encode songs to ogg opus:
* ffmpeg -i /path/to/song -c:a libopus -ar 48000 -ac 2 -vn -b:a 96K /path/to/opus.ogg
*/
dpp::cluster bot("token");
bot.on_log(dpp::utility::cout_logger());
/* The event is fired when someone issues your commands */
bot.on_slashcommand([&bot](const dpp::slashcommand_t& event) {
/* Check which command they ran */
if (event.command.get_command_name() == "join") {
/* Get the guild */
dpp::guild* g = dpp::find_guild(event.command.guild_id);
/* Attempt to connect to a voice channel, returns false if we fail to connect. */
if (!g->connect_member_voice(event.command.get_issuing_user().id)) {
event.reply("You don't seem to be in a voice channel!");
return;
}
/* Tell the user we joined their channel. */
event.reply("Joined your channel!");
} else if (event.command.get_command_name() == "play") {
/* Get the voice channel the bot is in, in this current guild. */
dpp::voiceconn* v = event.from->get_voice(event.command.guild_id);
/* If the voice channel was invalid, or there is an issue with it, then tell the user. */
if (!v || !v->voiceclient || !v->voiceclient->is_ready()) {
event.reply("There was an issue with getting the voice channel. Make sure I'm in a voice channel!");
return;
}
ogg_sync_state oy;
ogg_stream_state os;
ogg_page og;
ogg_packet op;
OpusHead header;
char *buffer;
FILE *fd;
fd = fopen("/path/to/opus.ogg", "rb");
fseek(fd, 0L, SEEK_END);
size_t sz = ftell(fd);
rewind(fd);
ogg_sync_init(&oy);
buffer = ogg_sync_buffer(&oy, sz);
fread(buffer, 1, sz, fd);
ogg_sync_wrote(&oy, sz);
/**
* We must first verify that the stream is indeed ogg opus
* by reading the header and parsing it
*/
if (ogg_sync_pageout(&oy, &og) != 1) {
fprintf(stderr,"Does not appear to be ogg stream.\n");
exit(1);
}
ogg_stream_init(&os, ogg_page_serialno(&og));
if (ogg_stream_pagein(&os,&og) < 0) {
fprintf(stderr,"Error reading initial page of ogg stream.\n");
exit(1);
}
if (ogg_stream_packetout(&os,&op) != 1) {
fprintf(stderr,"Error reading header packet of ogg stream.\n");
exit(1);
}
/* We must ensure that the ogg stream actually contains opus data */
if (!(op.bytes > 8 && !memcmp("OpusHead", op.packet, 8))) {
fprintf(stderr,"Not an ogg opus stream.\n");
exit(1);
}
/* Parse the header to get stream info */
int err = opus_head_parse(&header, op.packet, op.bytes);
if (err) {
fprintf(stderr,"Not a ogg opus stream\n");
exit(1);
}
/* Now we ensure the encoding is correct for Discord */
if (header.channel_count != 2 && header.input_sample_rate != 48000) {
fprintf(stderr,"Wrong encoding for Discord, must be 48000Hz sample rate with 2 channels.\n");
exit(1);
}
/* Now loop though all the pages and send the packets to the vc */
while (ogg_sync_pageout(&oy, &og) == 1) {
ogg_stream_init(&os, ogg_page_serialno(&og));
if(ogg_stream_pagein(&os,&og)<0) {
fprintf(stderr,"Error reading page of Ogg bitstream data.\n");
exit(1);
}
while (ogg_stream_packetout(&os,&op) != 0) {
/* Read remaining headers */
if (op.bytes > 8 && !memcmp("OpusHead", op.packet, 8)) {
int err = opus_head_parse(&header, op.packet, op.bytes);
if (err) {
fprintf(stderr,"Not a ogg opus stream\n");
exit(1);
}
if (header.channel_count != 2 && header.input_sample_rate != 48000) {
fprintf(stderr,"Wrong encoding for Discord, must be 48000Hz sample rate with 2 channels.\n");
exit(1);
}
continue;
}
/* Skip the opus tags */
if (op.bytes > 8 && !memcmp("OpusTags", op.packet, 8))
continue;
/* Send the audio */
int samples = opus_packet_get_samples_per_frame(op.packet, 48000);
v->voiceclient->send_audio_opus(op.packet, op.bytes, samples / 48);
}
}
/* Cleanup */
ogg_stream_clear(&os);
ogg_sync_clear(&oy);
event.reply("Finished playing the audio file!");
}
});
bot.on_ready([&bot](const dpp::ready_t & event) {
if (dpp::run_once<struct register_bot_commands>()) {
/* Create a new command. */
dpp::slashcommand joincommand("join", "Joins your voice channel.", bot.me.id);
dpp::slashcommand playcommand("play", "Plays an ogg file.", bot.me.id);
bot.global_bulk_command_create({ joincommand, playcommand });
}
});
/* Start bot */
bot.start(dpp::st_wait);
return 0;
}

View File

@@ -0,0 +1,114 @@
#include <dpp/dpp.h>
#include <iomanip>
#include <sstream>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <oggz/oggz.h>
int main() {
/* Load an ogg opus file into memory.
* The bot expects opus packets to be 2 channel stereo, 48000Hz.
*
* You may use ffmpeg to encode songs to ogg opus:
* ffmpeg -i /path/to/song -c:a libopus -ar 48000 -ac 2 -vn -b:a 96K /path/to/opus.ogg
*/
/* Setup the bot */
dpp::cluster bot("token");
bot.on_log(dpp::utility::cout_logger());
/* The event is fired when someone issues your commands */
bot.on_slashcommand([&bot](const dpp::slashcommand_t& event) {
/* Check which command they ran */
if (event.command.get_command_name() == "join") {
/* Get the guild */
dpp::guild* g = dpp::find_guild(event.command.guild_id);
/* Attempt to connect to a voice channel, returns false if we fail to connect. */
if (!g->connect_member_voice(event.command.get_issuing_user().id)) {
event.reply("You don't seem to be in a voice channel!");
return;
}
/* Tell the user we joined their channel. */
event.reply("Joined your channel!");
} else if (event.command.get_command_name() == "play") {
/* Get the voice channel the bot is in, in this current guild. */
dpp::voiceconn* v = event.from->get_voice(event.command.guild_id);
/* If the voice channel was invalid, or there is an issue with it, then tell the user. */
if (!v || !v->voiceclient || !v->voiceclient->is_ready()) {
event.reply("There was an issue with getting the voice channel. Make sure I'm in a voice channel!");
return;
}
/* load the audio file with oggz */
OGGZ *track_og = oggz_open("/path/to/opus.ogg", OGGZ_READ);
/* If there was an issue reading the file, tell the user and stop */
if (!track_og) {
fprintf(stderr, "Error opening file\n");
event.reply("There was an issue opening the file!");
return;
}
/* set read callback, this callback will be called on packets with the serialno,
* -1 means every packet will be handled with this callback.
*/
oggz_set_read_callback(
track_og, -1,
[](OGGZ *oggz, oggz_packet *packet, long serialno,
void *user_data) {
dpp::voiceconn *voiceconn = (dpp::voiceconn *)user_data;
/* send the audio */
voiceconn->voiceclient->send_audio_opus(packet->op.packet,
packet->op.bytes);
/* make sure to always return 0 here, read more on oggz documentation */
return 0;
},
/* this will be the value of void *user_data */
(void *)v
);
// read loop
while (v && v->voiceclient && !v->voiceclient->terminating) {
/* you can tweak this to whatever. Here I use BUFSIZ, defined in
* stdio.h as 8192.
*/
static const constexpr long CHUNK_READ = BUFSIZ * 2;
const long read_bytes = oggz_read(track_og, CHUNK_READ);
/* break on eof */
if (!read_bytes) {
break;
}
}
/* Don't forget to free the memory */
oggz_close(track_og);
event.reply("Finished playing the audio file!");
}
});
bot.on_ready([&bot](const dpp::ready_t & event) {
if (dpp::run_once<struct register_bot_commands>()) {
/* Create a new command. */
dpp::slashcommand joincommand("join", "Joins your voice channel.", bot.me.id);
dpp::slashcommand playcommand("play", "Plays an ogg file.", bot.me.id);
bot.global_bulk_command_create({ joincommand, playcommand });
}
});
/* Start bot */
bot.start(dpp::st_wait);
return 0;
}

View File

@@ -0,0 +1,62 @@
#include <dpp/dpp.h>
int main() {
/* Create the bot */
dpp::cluster bot("token");
bot.on_log(dpp::utility::cout_logger());
/* The event is fired when someone issues your commands */
bot.on_slashcommand([&bot](const dpp::slashcommand_t & event) {
/* Check which command they ran */
if (event.command.get_command_name() == "pm") {
dpp::snowflake user;
/* If there was no specified user, we set the "user" variable to the command author (issuing user). */
if (event.get_parameter("user").index() == 0) {
user = event.command.get_issuing_user().id;
} else { /* Otherwise, we set it to the specified user! */
user = std::get<dpp::snowflake>(event.get_parameter("user"));
}
/* Send a message to the user set above. */
bot.direct_message_create(user, dpp::message("Here's a private message!"), [event, user](const dpp::confirmation_callback_t& callback){
/* If the callback errors, we want to send a message telling the author that something went wrong. */
if (callback.is_error()) {
/* Here, we want the error message to be different if the user we're trying to send a message to is the command author. */
if (user == event.command.get_issuing_user().id) {
event.reply(dpp::message("I couldn't send you a message.").set_flags(dpp::m_ephemeral));
} else {
event.reply(dpp::message("I couldn't send a message to that user. Please check that is a valid user!").set_flags(dpp::m_ephemeral));
}
return;
}
/* We do the same here, so the message is different if it's to the command author or if it's to a specified user. */
if (user == event.command.get_issuing_user().id) {
event.reply(dpp::message("I've sent you a private message.").set_flags(dpp::m_ephemeral));
} else {
event.reply(dpp::message("I've sent a message to that user.").set_flags(dpp::m_ephemeral));
}
});
}
});
bot.on_ready([&bot](const dpp::ready_t& event) {
if (dpp::run_once<struct register_bot_commands>()) {
/* Register the command */
dpp::slashcommand command("pm", "Send a private message.", bot.me.id);
/* Add the option for a user mention that isn't required */
command.add_option(dpp::command_option(dpp::co_mentionable, "user", "The user to message", false));
/* Register the command */
bot.global_command_create(command);
}
});
bot.start(dpp::st_wait);
return 0;
}

View File

@@ -0,0 +1,66 @@
#include <dpp/dpp.h>
#include <iomanip>
#include <sstream>
int main() {
/* Example to record a user in a VC
*
* Recording is output as './me.pcm' and you can play it via the soundboard example
* or use ffmpeg 'ffplay -f s16le -ar 48000 -ac 2 -i ./me.pcm'
*/
/* Replace with the user's id you wish to record */
dpp::snowflake user_id = 407877550216314882;
/* Setup the bot */
dpp::cluster bot("token");
FILE *fd;
fd = fopen("./me.pcm", "wb");
bot.on_log(dpp::utility::cout_logger());
/* The event is fired when someone issues your commands */
bot.on_slashcommand([&bot, &fd](const dpp::slashcommand_t& event) {
/* Check which command they ran */
if (event.command.get_command_name() == "record") {
/* Get the guild */
dpp::guild* g = dpp::find_guild(event.command.guild_id);
/* Attempt to connect to a voice channel, returns false if we fail to connect. */
if (!g->connect_member_voice(event.command.get_issuing_user().id)) {
event.reply("You don't seem to be in a voice channel!");
return;
}
/* Tell the user we joined their channel. */
event.reply("Joined your channel, now recording!");
} else if (event.command.get_command_name() == "stop") {
event.from->disconnect_voice(event.command.guild_id);
fclose(fd);
event.reply("Stopped recording.");
}
});
bot.on_voice_receive([&bot, &fd, &user_id](const dpp::voice_receive_t &event) {
if (event.user_id == user_id) {
fwrite((char *)event.audio, 1, event.audio_size, fd);
}
});
bot.on_ready([&bot](const dpp::ready_t & event) {
if (dpp::run_once<struct register_bot_commands>()) {
/* Create a new command. */
dpp::slashcommand recordcommand("record", "Joins your voice channel and records you.", bot.me.id);
dpp::slashcommand stopcommand("stop", "Stops recording you.", bot.me.id);
bot.global_bulk_command_create({ recordcommand, stopcommand });
}
});
/* Start bot */
bot.start(dpp::st_wait);
return 0;
}

View File

@@ -0,0 +1,43 @@
#include <dpp/dpp.h>
int main() {
dpp::cluster bot("token");
bot.on_log(dpp::utility::cout_logger());
/* The event is fired when someone issues your commands */
bot.on_slashcommand([&bot](const dpp::slashcommand_t& event) {
/* Check which command they ran */
if (event.command.get_command_name() == "addrole") {
/* Fetch a parameter value from the command options */
dpp::snowflake user_id = std::get<dpp::snowflake>(event.get_parameter("user"));
dpp::snowflake role_id = std::get<dpp::snowflake>(event.get_parameter("role"));
/* Get member object from resolved list */
dpp::guild_member resolved_member = event.command.get_resolved_member(user_id);
resolved_member.add_role(role_id);
bot.guild_edit_member(resolved_member);
event.reply("Added role");
}
});
/* Attach on_ready event */
bot.on_ready([&bot](const dpp::ready_t& event) {
if (dpp::run_once<struct register_bot_commands>()) {
dpp::slashcommand add_role("addrole", "Give user a role", bot.me.id);
/* Add user and role type command options to the slash command */
add_role.add_option(dpp::command_option(dpp::co_user, "user", "User to give role to", true));
add_role.add_option(dpp::command_option(dpp::co_role, "role", "Role to give", true));
bot.global_command_create(add_role);
}
});
/* Start bot */
bot.start(dpp::st_wait);
return 0;
}

View File

@@ -0,0 +1,19 @@
#include <dpp/dpp.h>
int main() {
/* Create the bot */
dpp::cluster bot("token");
bot.on_log(dpp::utility::cout_logger());
bot.on_ready([&bot](const dpp::ready_t& event) {
/* We don't need the run_once here as we're not registering commands! */
/* Set the bot presence as online and "Playing..."! */
bot.set_presence(dpp::presence(dpp::ps_online, dpp::at_game, "games!"));
});
bot.start(dpp::st_wait);
return 0;
}

View File

@@ -0,0 +1,25 @@
#include <dpp/dpp.h>
int main() {
/* Create the bot */
dpp::cluster bot("token");
bot.on_log(dpp::utility::cout_logger());
bot.on_ready([&bot](const dpp::ready_t& event) {
/* We put our status updating inside "run_once" so that multiple shards don't try do this as "set_presence" updates all the shards. */
if (dpp::run_once<struct register_bot_commands>()) {
/* We update the presence now as the timer will do the first execution after the x amount of seconds we specify */
bot.set_presence(dpp::presence(dpp::presence_status::ps_online, dpp::activity_type::at_game, "with " + std::to_string(event.guild_count) + " guilds!"));
/* Create a timer that runs every 120 seconds, that sets the status */
bot.start_timer([&bot](const dpp::timer& timer) {
bot.set_presence(dpp::presence(dpp::presence_status::ps_online, dpp::activity_type::at_game, "with " + std::to_string(dpp::get_guild_cache()->count()) + " guilds!"));
}, 120);
}
});
bot.start(dpp::st_wait);
return 0;
}

View File

@@ -0,0 +1,41 @@
#include <dpp/dpp.h>
int main() {
dpp::cluster bot("token");
bot.on_log(dpp::utility::cout_logger());
/* The event is fired when someone issues your commands */
bot.on_slashcommand([&bot](const dpp::slashcommand_t & event) {
/* Check which command they ran */
if (event.command.get_command_name() == "blep") {
/* Fetch a parameter value from the command parameters */
std::string animal = std::get<std::string>(event.get_parameter("animal"));
/* Reply to the command. There is an overloaded version of this
* call that accepts a dpp::message so you can send embeds.
*/
event.reply(std::string("Blep! You chose") + animal);
}
});
bot.on_ready([&bot](const dpp::ready_t & event) {
if (dpp::run_once<struct register_bot_commands>()) {
/* Create a new global command on ready event */
dpp::slashcommand newcommand("blep", "Send a random adorable animal photo", bot.me.id);
newcommand.add_option(
dpp::command_option(dpp::co_string, "animal", "The type of animal", true)
.add_choice(dpp::command_option_choice("Dog", std::string("animal_dog")))
.add_choice(dpp::command_option_choice("Cat", std::string("animal_cat")))
.add_choice(dpp::command_option_choice("Penguin", std::string("animal_penguin")))
);
/* Register the command */
bot.global_command_create(newcommand);
}
});
bot.start(dpp::st_wait);
return 0;
}

View File

@@ -0,0 +1,41 @@
#include <dpp/dpp.h>
int main() {
dpp::cluster bot("token");
bot.on_log(dpp::utility::cout_logger());
/* The event is fired when someone issues your commands */
bot.on_slashcommand([&bot](const dpp::slashcommand_t & event) {
/* Check which command they ran */
if (event.command.get_command_name() == "blep") {
/* Fetch a parameter value from the command parameters */
std::string animal = std::get<std::string>(event.get_parameter("animal"));
/* Reply to the command. There is an overloaded version of this
* call that accepts a dpp::message so you can send embeds.
*/
event.reply(std::string("Blep! You chose") + animal);
}
});
bot.on_ready([&bot](const dpp::ready_t & event) {
if (dpp::run_once<struct register_bot_commands>()) {
/* Create a new global command on ready event */
dpp::slashcommand newcommand("blep", "Send a random adorable animal photo", bot.me.id);
newcommand.add_option(
dpp::command_option(dpp::co_string, "animal", "The type of animal", true)
.add_choice(dpp::command_option_choice("Dog", std::string("animal_dog")))
.add_choice(dpp::command_option_choice("Cat", std::string("animal_cat")))
.add_choice(dpp::command_option_choice("Penguin", std::string("animal_penguin")))
);
/* Register the command */
bot.guild_command_create(newcommand, 857692897221033129); /* Replace this with the guild id you want */
}
});
bot.start(dpp::st_wait);
return 0;
}

View File

@@ -0,0 +1,38 @@
#include <dpp/dpp.h>
int main() {
dpp::cluster bot("token");
bot.on_log(dpp::utility::cout_logger());
/* The event is fired when someone issues your commands */
bot.on_slashcommand([&bot](const dpp::slashcommand_t & event) {
/* Check which command they ran */
if (event.command.get_command_name() == "ping") {
event.reply("Pong!");
} else if (event.command.get_command_name() == "pong") {
event.reply("Ping!");
} else if (event.command.get_command_name() == "ding") {
event.reply("Dong!");
} else if (event.command.get_command_name() == "dong") {
event.reply("Ding!");
}
});
bot.on_ready([&bot](const dpp::ready_t & event) {
if (dpp::run_once<struct register_bot_commands>()) {
/* Create some commands */
dpp::slashcommand pingcommand("ping", "Pong!", bot.me.id);
dpp::slashcommand pongcommand("pong", "Ping!", bot.me.id);
dpp::slashcommand dingcommand("ding", "Dong!", bot.me.id);
dpp::slashcommand dongcommand("dong", "Ding!", bot.me.id);
/* Register our commands in a list using bulk */
bot.global_bulk_command_create({ pingcommand, pongcommand, dingcommand, dongcommand });
}
});
bot.start(dpp::st_wait);
return 0;
}

View File

@@ -0,0 +1,38 @@
#include <dpp/dpp.h>
int main() {
dpp::cluster bot("token");
bot.on_log(dpp::utility::cout_logger());
/* The event is fired when someone issues your commands */
bot.on_slashcommand([&bot](const dpp::slashcommand_t & event) {
/* Check which command they ran */
if (event.command.get_command_name() == "ping") {
event.reply("Pong!");
} else if (event.command.get_command_name() == "pong") {
event.reply("Ping!");
} else if (event.command.get_command_name() == "ding") {
event.reply("Dong!");
} else if (event.command.get_command_name() == "dong") {
event.reply("Ding!");
}
});
bot.on_ready([&bot](const dpp::ready_t & event) {
if (dpp::run_once<struct register_bot_commands>()) {
/* Create some commands */
dpp::slashcommand pingcommand("ping", "Pong!", bot.me.id);
dpp::slashcommand pongcommand("pong", "Ping!", bot.me.id);
dpp::slashcommand dingcommand("ding", "Dong!", bot.me.id);
dpp::slashcommand dongcommand("dong", "Ding!", bot.me.id);
/* Register our commands in a list using bulk */
bot.guild_bulk_command_create({ pingcommand, pongcommand, dingcommand, dongcommand }, 857692897221033129);
}
});
bot.start(dpp::st_wait);
return 0;
}

View File

@@ -0,0 +1,80 @@
#include <dpp/dpp.h>
#include <iomanip>
#include <sstream>
int main() {
/* Load a sound file called Robot.pcm into memory.
* The bot expects PCM format, which are raw sound data,
* 2 channel stereo, 16 bit signed 48000Hz.
*
* You can use audacity to export these from WAV or MP3 etc.
*
* If you wanted to send a more complicated format, you could
* use a separate library to decode that audio to PCM. For
* example purposes, a raw PCM will suffice. This PCM file can
* be found within the bot's github repo.
*/
uint8_t* robot = nullptr;
size_t robot_size = 0;
std::ifstream input ("../testdata/Robot.pcm", std::ios::in|std::ios::binary|std::ios::ate);
if (input.is_open()) {
robot_size = input.tellg();
robot = new uint8_t[robot_size];
input.seekg (0, std::ios::beg);
input.read ((char*)robot, robot_size);
input.close();
}
/* Setup the bot */
dpp::cluster bot("token");
bot.on_log(dpp::utility::cout_logger());
/* The event is fired when someone issues your commands */
bot.on_slashcommand([&bot, robot, robot_size](const dpp::slashcommand_t& event) {
/* Check which command they ran */
if (event.command.get_command_name() == "join") {
/* Get the guild */
dpp::guild* g = dpp::find_guild(event.command.guild_id);
/* Attempt to connect to a voice channel, returns false if we fail to connect. */
if (!g->connect_member_voice(event.command.get_issuing_user().id)) {
event.reply("You don't seem to be in a voice channel!");
return;
}
/* Tell the user we joined their channel. */
event.reply("Joined your channel!");
} else if (event.command.get_command_name() == "robot") {
/* Get the voice channel the bot is in, in this current guild. */
dpp::voiceconn* v = event.from->get_voice(event.command.guild_id);
/* If the voice channel was invalid, or there is an issue with it, then tell the user. */
if (!v || !v->voiceclient || !v->voiceclient->is_ready()) {
event.reply("There was an issue with getting the voice channel. Make sure I'm in a voice channel!");
return;
}
/* Tell the bot to play the sound file 'Robot.pcm' in the current voice channel. */
v->voiceclient->send_audio_raw((uint16_t*)robot, robot_size);
event.reply("Played robot.");
}
});
bot.on_ready([&bot](const dpp::ready_t & event) {
if (dpp::run_once<struct register_bot_commands>()) {
/* Create a new command. */
dpp::slashcommand joincommand("join", "Joins your voice channel.", bot.me.id);
dpp::slashcommand robotcommand("robot", "Plays a robot noise in your voice channel.", bot.me.id);
bot.global_bulk_command_create({ joincommand, robotcommand });
}
});
/* Start bot */
bot.start(dpp::st_wait);
return 0;
}

View File

@@ -0,0 +1,66 @@
#include <dpp/dpp.h>
#include <iostream>
int main() {
dpp::cluster bot("token");
bot.on_log(dpp::utility::cout_logger());
/* Use the on_slashcommand event to look for commands */
bot.on_slashcommand([&bot](const dpp::slashcommand_t & event) {
dpp::command_interaction cmd_data = event.command.get_command_interaction();
/* Check if the command is the image command. */
if (event.command.get_command_name() == "image") {
/* Get the sub command */
auto subcommand = cmd_data.options[0];
/* Check if the subcommand is "dog" */
if (subcommand.name == "dog") {
/* Checks if the subcommand has any options. */
if (!subcommand.options.empty()) {
/* Get the user from the parameter */
dpp::user user = event.command.get_resolved_user(subcommand.get_value<dpp::snowflake>(0));
event.reply(user.get_mention() + " has now been turned into a dog.");
} else {
/* Reply if there were no options.. */
event.reply("No user specified");
}
} else if (subcommand.name == "cat") { /* Check if the subcommand is "cat". */
/* Checks if the subcommand has any options. */
if (!subcommand.options.empty()) {
/* Get the user from the parameter */
dpp::user user = event.command.get_resolved_user(subcommand.get_value<dpp::snowflake>(0));
event.reply(user.get_mention() + " has now been turned into a cat.");
} else {
/* Reply if there were no options.. */
event.reply("No user specified");
}
}
}
});
/* Executes on ready. */
bot.on_ready([&bot](const dpp::ready_t & event) {
if (dpp::run_once<struct register_bot_commands>()) {
/* Define a slash command. */
dpp::slashcommand image("image", "Send a specific image.", bot.me.id);
image.add_option(
/* Create a subcommand type option for "dog". */
dpp::command_option(dpp::co_sub_command, "dog", "Send a picture of a dog.")
.add_option(dpp::command_option(dpp::co_user, "user", "User to turn into a dog.", false))
);
image.add_option(
/* Create another subcommand type option for "cat". */
dpp::command_option(dpp::co_sub_command, "cat", "Send a picture of a cat.")
.add_option(dpp::command_option(dpp::co_user, "user", "User to turn into a cat.", false))
);
/* Create command */
bot.global_command_create(image);
}
});
bot.start(dpp::st_wait);
return 0;
}

View File

@@ -0,0 +1,39 @@
#include <dpp/dpp.h>
int main() {
dpp::cluster bot("token");
bot.on_log(dpp::utility::cout_logger());
/* The event is fired when someone issues your commands */
bot.on_slashcommand([&bot](const dpp::slashcommand_t& event) {
/* Check which command they ran */
if (event.command.get_command_name() == "show") {
/* Get the file id from the parameter attachment. */
dpp::snowflake file_id = std::get<dpp::snowflake>(event.get_parameter("file"));
/* Get the attachment that the user inputted from the file id. */
dpp::attachment att = event.command.get_resolved_attachment(file_id);
/* Reply with the file as a URL. */
event.reply(att.url);
}
});
bot.on_ready([&bot](const dpp::ready_t & event) {
if (dpp::run_once<struct register_bot_commands>()) {
/* Create a new command. */
dpp::slashcommand newcommand("show", "Show an uploaded file", bot.me.id);
/* Add a parameter option. */
newcommand.add_option(dpp::command_option(dpp::co_attachment, "file", "Select an image"));
/* Register the command */
bot.global_command_create(newcommand);
}
});
bot.start(dpp::st_wait);
return 0;
}

View File

@@ -0,0 +1,26 @@
#include <dpp/dpp.h>
int main() {
/* Create bot */
dpp::cluster bot("token", dpp::i_default_intents | dpp::i_guild_members);
bot.on_log(dpp::utility::cout_logger());
/* This event is fired when someone removes their reaction from a message */
bot.on_message_reaction_remove([&bot](const dpp::message_reaction_remove_t& event) {
/* Find the user in the cache using his discord id */
dpp::user* reacting_user = dpp::find_user(event.reacting_user_id);
/* If user not found in cache, log and return */
if (!reacting_user) {
bot.log(dpp::ll_info, "User with the id " + std::to_string(event.reacting_user_id) + " was not found.");
return;
}
bot.log(dpp::ll_info, reacting_user->format_username() + " removed his reaction.");
});
bot.start(dpp::st_wait);
return 0;
}

View File

@@ -0,0 +1,29 @@
#include <dpp/dpp.h>
#include <dpp/unicode_emoji.h>
int main() {
dpp::cluster bot("Epic Token");
bot.on_log(dpp::utility::cout_logger());
/* We'll be using two emojis: shocked guy and animated mad face. */
dpp::emoji shocked("vahuyi", 1179366531856093214);
dpp::emoji mad("mad", 1117795317052616704, dpp::e_animated); /* We need this third argument, which is an emoji flag. */
bot.on_slashcommand([shocked, mad](const dpp::slashcommand_t& event) {
if (event.command.get_command_name() == "send-emojis") {
/* Here we send our very informative message: three epic emojis. */
event.reply(dpp::unicode_emoji::nerd + shocked.get_mention() + mad.get_mention());
}
});
bot.on_ready([&bot](const dpp::ready_t& event) {
if (dpp::run_once<struct register_bot_commands>()) {
bot.global_command_create(dpp::slashcommand("send-emojis", "Send the emojis", bot.me.id));
}
});
/* Start the bot! */
bot.start(dpp::st_wait);
return 0;
}

View File

@@ -0,0 +1,35 @@
#include <dpp/dpp.h>
#include <dpp/unicode_emoji.h>
int main() {
dpp::cluster bot("Epic Token", dpp::i_default_intents | dpp::i_message_content);
/* The second argument is a bitmask of intents - i_message_content is needed to see the messages */
bot.on_log(dpp::utility::cout_logger());
/* We'll be using a shocked guy emoji */
dpp::emoji shocked("vahuyi", 1179366531856093214);
dpp::emoji mad("mad", 1117795317052616704, dpp::e_animated); /* We need this third argument, which is an emoji flag. */
bot.on_message_create([&bot, shocked, mad](const dpp::message_create_t& event) {
if (event.msg.content == "I'm hungry") {
/* But if they're hungry */
bot.message_add_reaction(event.msg.id, event.msg.channel_id, dpp::unicode_emoji::cut_of_meat);
/* Let's send some meat to the message, so they don't starve. They will thank us later. */
} else if (event.msg.content == "WHAT?") {
/* If some unknown content shocked the user */
bot.message_add_reaction(event.msg.id, event.msg.channel_id, shocked.format());
/* React to their message with a shocked guy */
} else if (event.msg.content == "I'm unsubscribing") {
/* They are angry! We should also be! */
bot.message_add_reaction(event.msg.id, event.msg.channel_id, mad.format());
/* React to their message with a mad emoji */
}
});
/* Start the bot! */
bot.start(dpp::st_wait);
return 0;
}

View File

@@ -0,0 +1,45 @@
#include <dpp/dpp.h>
#include <dpp/unicode_emoji.h>
int main() {
dpp::cluster bot("Epic Token");
bot.on_log(dpp::utility::cout_logger());
/* We now have a new character! That's for the select menu. */
dpp::emoji walter("walter_black", 1179374919088361544);
dpp::emoji mad("mad", 1117795317052616704, dpp::e_animated); /* We need this third argument, which is an emoji flag. */
/* The event is fired when someone issues your commands */
bot.on_slashcommand([walter, mad](const dpp::slashcommand_t& event) {
if (event.command.get_command_name() == "select") {
dpp::message msg(event.command.channel_id, "Now.");
msg.add_component(
dpp::component().add_component(
dpp::component()
.set_type(dpp::cot_selectmenu)
.set_placeholder("Say my name.")
.add_select_option(dpp::select_option("Do what?", "Yeah, you do.", "I don't have a damn clue what you're talking about.").set_emoji(dpp::unicode_emoji::thinking))
.add_select_option(dpp::select_option("Heisenberg", "You're goddamn right!", "The one and only").set_emoji(walter.name, walter.id))
.add_select_option(dpp::select_option("I'm unsubscribing", "Wait what", "Pure cruelty").set_emoji(mad.name, mad.id, mad.is_animated())) /* Since our mad emoji is animated, we should tell that to the function */
.set_id("myselectid")
)
);
event.reply(msg);
}
});
bot.on_select_click([](const dpp::select_click_t& event) {
event.reply(event.values[0]);
});
bot.on_ready([&bot](const dpp::ready_t& event) {
if (dpp::run_once<struct register_bot_commands>()) {
bot.global_command_create(dpp::slashcommand("select", "Send the select menu", bot.me.id));
}
});
/* Start the bot! */
bot.start(dpp::st_wait);
return 0;
}

View File

@@ -0,0 +1,16 @@
#include <dpp/dpp.h>
int main()
{
dpp::cluster bot(""); /* Normally, you put your bot token in here, but its not required for webhooks. */
bot.on_log(dpp::utility::cout_logger());
/* Construct a webhook object using the URL you got from Discord */
dpp::webhook wh("https://discord.com/api/webhooks/833047646548133537/ntCHEYYIoHSLy_GOxPx6pmM0sUoLbP101ct-WI6F-S4beAV2vaIcl_Id5loAMyQwxqhE");
/* Send a message with this webhook */
bot.execute_webhook_sync(wh, dpp::message("Have a great time here :smile:"));
return 0;
}