diff --git a/Discord.C++/Emoji.cpp b/Discord.C++/Emoji.cpp index 2a4cd4d..c1bb4b5 100644 --- a/Discord.C++/Emoji.cpp +++ b/Discord.C++/Emoji.cpp @@ -19,6 +19,21 @@ DiscordCPP::Emoji::Emoji(const json& data, const std::string& token) available = get_or_else(data, "available", true); } +DiscordCPP::Emoji DiscordCPP::Emoji::by_name(const std::string& name) { + Emoji emoji = Emoji(); + emoji.name = name; + + return emoji; +} + +std::string DiscordCPP::Emoji::url_encode() { + std::string url_encoded = urlencode(name.value_or("")); + if (get_id().has_value()) { + url_encoded.append(urlencode(":" + get_id().value())); + } + return url_encoded; +} + std::optional DiscordCPP::Emoji::get_id() { if (DiscordCPP::DiscordObject::get_id() == "") { return {}; diff --git a/Discord.C++/Emoji.h b/Discord.C++/Emoji.h index b502f93..dbf5a5f 100644 --- a/Discord.C++/Emoji.h +++ b/Discord.C++/Emoji.h @@ -28,22 +28,26 @@ class Emoji : public DiscordObject { public: DLL_EXPORT Emoji() = default; DLL_EXPORT Emoji(const json& data, const std::string& token); + DLL_EXPORT static Emoji by_name(const std::string& name); + + /// @return url encoded string in the format name:id + DLL_EXPORT std::string url_encode(); /// @return emoji id - std::optional get_id(); + DLL_EXPORT std::optional get_id(); /// @return emoji name - std::optional get_name() { return name; } + DLL_EXPORT std::optional get_name() { return name; } /// @return roles allowed to use this emoji - std::vector get_role_ids() { return role_ids; } + DLL_EXPORT std::vector get_role_ids() { return role_ids; } /// @return user that created this emoji - std::optional get_user() { return user; } + DLL_EXPORT std::optional get_user() { return user; } /// @return wether this emoji must be wrapped in colons - bool requires_colons() { return require_colons; } + DLL_EXPORT bool requires_colons() { return require_colons; } /// @return wether this emoji is managed - bool is_managed() { return managed; } + DLL_EXPORT bool is_managed() { return managed; } /// @return wether this emoji is animated - bool is_animated() { return animated; } + DLL_EXPORT bool is_animated() { return animated; } /// @return whether this emoji can be used, may be false due to loss of Server Boosts - bool is_available() { return available; } + DLL_EXPORT bool is_available() { return available; } }; } // namespace DiscordCPP diff --git a/Discord.C++/Message.cpp b/Discord.C++/Message.cpp index 1faba57..2dffc31 100644 --- a/Discord.C++/Message.cpp +++ b/Discord.C++/Message.cpp @@ -140,6 +140,40 @@ DiscordCPP::Message DiscordCPP::Message::reply(DiscordCPP::Embed embed) { return {api_call(url, "POST", data, "application/json"), get_token()}; } +DiscordCPP::Message DiscordCPP::Message::crosspost(DiscordCPP::TextChannel channel) { + std::string url = "/channels/" + channel.get_id() + "/messages/" + get_id() + "/crosspost"; + return {api_call(url, "POST"), get_token()}; +} + +void DiscordCPP::Message::add_reaction(DiscordCPP::Emoji emoji) { + std::string url = "/channels/" + channel_id + "/messages/" + get_id() + + "/reactions/" + emoji.url_encode() + "/@me"; + api_call(url, "PUT"); +} + +void DiscordCPP::Message::remove_reaction(DiscordCPP::Emoji emoji) { + std::string url = "/channels/" + channel_id + "/messages/" + get_id() + + "/reactions/" + emoji.url_encode() + "/@me"; + api_call(url, "DELETE"); +} + +void DiscordCPP::Message::remove_user_reaction(DiscordCPP::Emoji emoji, DiscordCPP::User user) { + std::string url = "/channels/" + channel_id + "/messages/" + get_id() + + "/reactions/" + emoji.url_encode() + "/" + user.get_id(); + api_call(url, "DELETE"); +} + +void DiscordCPP::Message::remove_all_reactions() { + std::string url = "/channels/" + channel_id + "/messages/" + get_id() + "/reactions"; + api_call(url, "DELETE"); +} + +void DiscordCPP::Message::remove_all_reactions(DiscordCPP::Emoji emoji) { + std::string url = "/channels/" + channel_id + "/messages/" + get_id() + + "/reactions/" + emoji.url_encode(); + api_call(url, "DELETE"); +} + DiscordCPP::TextChannel DiscordCPP::Message::get_channel() { if (channel == nullptr) { channel = new TextChannel(channel_id, get_token()); diff --git a/Discord.C++/Message.h b/Discord.C++/Message.h index dcc34a1..503e5ed 100644 --- a/Discord.C++/Message.h +++ b/Discord.C++/Message.h @@ -1,7 +1,10 @@ #pragma once +#include + #include "DiscordObject.h" #include "Embed.h" +#include "Emoji.h" #include "MessageReaction.h" #include "User.h" @@ -75,7 +78,18 @@ class Message : public DiscordObject { DLL_EXPORT Message reply(const std::string& content, const bool tts = false); /// Send an Embed as reply to this message. DLL_EXPORT Message reply(Embed embed); - // TODO: add_reaction + /// Crosspost this message to another channel + DLL_EXPORT Message crosspost(TextChannel channel); + /// Add a reaction + DLL_EXPORT void add_reaction(Emoji emoji); + /// Remove own reaction + DLL_EXPORT void remove_reaction(Emoji emoji); + /// Remove another user's reaction + DLL_EXPORT void remove_user_reaction(Emoji emoji, User user); + /// Remove all reactions + DLL_EXPORT void remove_all_reactions(); + /// Remove all reactions by emoji + DLL_EXPORT void remove_all_reactions(Emoji emoji); /// @return The id of the Channel the message was sent in DLL_EXPORT std::string get_channel_id() { return channel_id; } diff --git a/test_bot/main.cpp b/test_bot/main.cpp index 008bd99..abbe16b 100644 --- a/test_bot/main.cpp +++ b/test_bot/main.cpp @@ -98,6 +98,11 @@ class Client : public Discord { say.add_option(m); create_application_command(say); + ApplicationCommand react = ApplicationCommand(); + react.set_name("react"); + react.set_type(ApplicationCommand::Type::MESSAGE); + create_application_command(react); + update_presence(DiscordStatus::Online, Activity("test", Activity::Type::Game)); } @@ -424,6 +429,34 @@ class Client : public Discord { log.info(InteractionDataOptionHelper::get_interaction_data_option_name(option) + " " + std::to_string(InteractionDataOptionHelper::get_interaction_data_option_type(option))); } } + } else if (name == "react") { + auto data = interaction.get_data().value(); + if (data.get_resolved_data().has_value() && data.get_target_id().has_value()) { + Message message = data.get_resolved_data().value().get_messages().at(data.get_target_id().value()); + interaction.reply(":100:"); + + Emoji thumbs_up = Emoji::by_name("👍"); + Emoji thumbs_down = Emoji::by_name("👎"); + Emoji e100 = Emoji::by_name("💯"); + + message.add_reaction(thumbs_up); + this_thread::sleep_for(chrono::seconds(1)); + message.add_reaction(thumbs_down); + this_thread::sleep_for(chrono::seconds(1)); + message.add_reaction(e100); + this_thread::sleep_for(chrono::seconds(1)); + + message.remove_reaction(thumbs_down); + this_thread::sleep_for(chrono::seconds(1)); + message.remove_user_reaction(thumbs_up, *_user); + this_thread::sleep_for(chrono::seconds(1)); + message.remove_all_reactions(e100); + this_thread::sleep_for(chrono::seconds(1)); + + message.add_reaction(e100); + this_thread::sleep_for(chrono::seconds(1)); + message.remove_all_reactions(); + } } }