Skip to content

Commit 872e81e

Browse files
committed
implement functions to add/remove roles from members
1 parent cee8c6e commit 872e81e

10 files changed

+87
-15
lines changed

Discord.C++/ApplicationCommand.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,6 @@ class ApplicationCommand : public DiscordObject {
110110
/// Add interaction context where the command can be used.
111111
DLL_EXPORT void add_contexts(ContextType context) { contexts.push_back(context); }
112112
/// Set the handler type for PRIMARY_ENTRY_POINT.
113-
DLL_EXPORT void get_handler(HandlerType handler) { this->handler.emplace(handler); }
113+
DLL_EXPORT void set_handler(HandlerType handler) { this->handler.emplace(handler); }
114114
};
115115
} // namespace DiscordCPP

Discord.C++/Interaction.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ DiscordCPP::Interaction::Interaction(const json& data, const std::string& token)
88
type(static_cast<Type>(data.at("type").get<int>())) {
99
data.at("application_id").get_to<std::string>(application_id);
1010

11+
guild_id = get_optional<std::string>(data, "guild_id");
1112
if (has_value(data, "data")) {
12-
this->data.emplace(data.at("data"), token);
13+
this->data.emplace(data.at("data"), token, guild_id.value_or(""));
1314
}
14-
guild_id = get_optional<std::string>(data, "guild_id");
1515
channel_id = get_optional<std::string>(data, "channel_id");
1616
if (has_value(data, "member")) {
1717
member.emplace(data.at("member"), token);

Discord.C++/InteractionData.cpp

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#include "InteractionData.h"
22

3-
DiscordCPP::InteractionData::InteractionData(const json& data, const std::string& token)
3+
DiscordCPP::InteractionData::InteractionData(const json& data, const std::string& token, const std::string& guild_id)
44
: DiscordCPP::DiscordObject(token, data.at("id").get<std::string>()),
55
name(data.at("name").get<std::string>()),
66
type(static_cast<ApplicationCommand::Type>(data.at("type").get<int>())) {
@@ -9,9 +9,8 @@ DiscordCPP::InteractionData::InteractionData(const json& data, const std::string
99
options.push_back(InteractionDataOptionHelper::interaction_data_option_from_json(option));
1010
}
1111
}
12-
guild_id = get_optional<std::string>(data, "guild_id");
1312
if (has_value(data, "resolved")) {
14-
resolved_data = InteractionResolvedData(data.at("resolved"), guild_id.value_or(""), token);
13+
resolved_data = InteractionResolvedData(data.at("resolved"), guild_id, token);
1514
}
1615
custom_id = get_optional<std::string>(data, "custom_id");
1716
target_id = get_optional<std::string>(data, "target_id");

Discord.C++/InteractionData.h

+1-5
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@ class InteractionData : public DiscordObject {
1919
std::optional<InteractionResolvedData> resolved_data;
2020
/// The parameters and values from the user.
2121
std::vector<InteractionDataOptionVariant> options;
22-
/// The id of the guild the command is registered to.
23-
std::optional<std::string> guild_id;
2422
/// Id the of user or message targeted by a user or message command.
2523
std::optional<std::string> target_id;
2624
/// The custom id of the component.
@@ -30,7 +28,7 @@ class InteractionData : public DiscordObject {
3028
// components
3129

3230
public:
33-
DLL_EXPORT InteractionData(const json& data, const std::string& token);
31+
DLL_EXPORT InteractionData(const json& data, const std::string& token, const std::string& guild_id);
3432

3533
/// @return name of the invoked command.
3634
DLL_EXPORT std::string get_name() { return name; }
@@ -40,8 +38,6 @@ class InteractionData : public DiscordObject {
4038
DLL_EXPORT std::optional<InteractionResolvedData> get_resolved_data() { return resolved_data; }
4139
/// @return The parameters and values from the user.
4240
DLL_EXPORT std::vector<InteractionDataOptionVariant> get_options() { return options; }
43-
/// @return The id of the guild the command is registered to.
44-
DLL_EXPORT std::optional<std::string> get_guild_id() { return guild_id; }
4541
/// @return Id the of user or message targeted by a user or message command.
4642
DLL_EXPORT std::optional<std::string> get_target_id() { return target_id; }
4743
/// @return The custom id of the component.

Discord.C++/InteractionResolvedData.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ DiscordCPP::InteractionResolvedData::InteractionResolvedData(const json& data, c
1111

1212
if (has_value(data, "members")) {
1313
for (auto [key, value] : data["members"].items()) {
14-
members.insert(std::make_pair(key, Member(value, token)));
14+
json member_json = value;
15+
member_json["user"] = data["users"][key];
16+
members.insert(std::make_pair(key, Member(member_json, token)));
1517
}
1618
}
1719

Discord.C++/Member.cpp

+22
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,25 @@ DiscordCPP::Member::operator std::string() {
1818
else
1919
return nick;
2020
}
21+
22+
void DiscordCPP::Member::add_role(const DiscordCPP::Role& role) {
23+
std::string url = "/guilds/" + role.get_guild_id() + "/members/" + get_id();
24+
25+
role_ids.push_back(role.get_id());
26+
json data = {{"roles", role_ids}};
27+
28+
api_call(url, "PATCH", data, "application/json", false);
29+
}
30+
31+
void DiscordCPP::Member::remove_role(const DiscordCPP::Role& role) {
32+
std::string url = "/guilds/" + role.get_guild_id() + "/members/" + get_id();
33+
34+
role_ids.erase(std::remove_if(role_ids.begin(),
35+
role_ids.end(),
36+
[role](std::string i) {
37+
return role.get_id() == i;
38+
}));
39+
json data = {{"roles", role_ids}};
40+
41+
api_call(url, "PATCH", data, "application/json", false);
42+
}

Discord.C++/Member.h

+8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#pragma once
22

3+
#include "Role.h"
34
#include "User.h"
45
#include "static.h"
56

@@ -22,6 +23,13 @@ class Member : public User {
2223
DLL_EXPORT Member(const json& data, const std::string& token);
2324
DLL_EXPORT Member() = default;
2425

26+
/** Assign the given role to this member.
27+
@param[in] role the role to assign */
28+
DLL_EXPORT void add_role(const Role& role);
29+
/** Remove the given role from this member.
30+
@param[in] role the role to remove */
31+
DLL_EXPORT void remove_role(const Role& role);
32+
2533
///@return Nickname (Username if not present) as std::string
2634
DLL_EXPORT explicit operator std::string() override;
2735

Discord.C++/Role.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ class Role : public DiscordObject {
4444
*/
4545
DLL_EXPORT void delete_role();
4646

47+
/// @return the role's guild id
48+
DLL_EXPORT std::string get_guild_id() const { return guild_id; }
4749
/// @return role name
4850
DLL_EXPORT std::string get_name() const { return name; }
4951
/// @return integer representation of hexadecimal color code
@@ -65,8 +67,7 @@ class Role : public DiscordObject {
6567
/// @return role flags combined as a bitfield
6668
DLL_EXPORT int get_flags() const { return flags; }
6769
/** @param[in] flag the Flag to check
68-
* @return true if the role has the given flag
69-
*/
70+
* @return true if the role has the given flag */
7071
DLL_EXPORT bool has_flag(Flag flag) const { return flags & flag; }
7172
};
7273
} // namespace DiscordCPP

Discord.C++/User.h

-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
#pragma once
2-
#include <iostream>
32

43
#include "DiscordObject.h"
54
#include "Logger.h"

test_bot/main.cpp

+45
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,38 @@ class Client : public Discord {
113113
permissions.add_integration_types(DiscordCPP::ApplicationCommand::GUILD_INSTALL);
114114
create_application_command(permissions);
115115

116+
ApplicationCommand role_cmd;
117+
role_cmd.set_name("role");
118+
role_cmd.set_description("add/remove roles from a member");
119+
role_cmd.set_type(DiscordCPP::ApplicationCommand::CHAT_INPUT);
120+
role_cmd.add_contexts(DiscordCPP::ApplicationCommand::GUILD);
121+
role_cmd.add_integration_types(DiscordCPP::ApplicationCommand::GUILD_INSTALL);
122+
ApplicationCommandValueOption member;
123+
member.set_type(DiscordCPP::ApplicationCommandOption::USER);
124+
member.set_name("member");
125+
member.set_description("member");
126+
member.set_required(true);
127+
ApplicationCommandValueOption role;
128+
role.set_type(DiscordCPP::ApplicationCommandOption::ROLE);
129+
role.set_name("role");
130+
role.set_description("role");
131+
role.set_required(true);
132+
ApplicationCommandSubcommand add;
133+
add.set_type(DiscordCPP::ApplicationCommandOption::SUB_COMMAND);
134+
add.set_name("add");
135+
add.set_description("assign role to member");
136+
add.add_option(member);
137+
add.add_option(role);
138+
ApplicationCommandSubcommand remove;
139+
remove.set_type(DiscordCPP::ApplicationCommandOption::SUB_COMMAND);
140+
remove.set_name("remove");
141+
remove.set_description("remove role from member");
142+
remove.add_option(member);
143+
remove.add_option(role);
144+
role_cmd.add_option(add);
145+
role_cmd.add_option(remove);
146+
create_application_command(role_cmd);
147+
116148
update_presence(DiscordStatus::Online, Activity("test", Activity::Type::Game));
117149
}
118150

@@ -481,6 +513,19 @@ class Client : public Discord {
481513
+ "\nYou are " + std::string(can_delete_messages ? "" : "not ") + "allowed to delete messages" //
482514
+ "\nYou can " + std::string(can_kick_members ? "" : "not ") + "kick members");
483515
}
516+
} else if (name == "role") {
517+
auto options = interaction.get_data().value().get_options();
518+
auto member = interaction.get_data()->get_resolved_data()->get_members().begin()->second;
519+
auto role = interaction.get_data()->get_resolved_data()->get_roles().begin()->second;
520+
for (auto& option : options) {
521+
if (InteractionDataOptionHelper::get_interaction_data_option_name(option) == "add" && InteractionDataOptionHelper::get_interaction_data_option_type(option) == ApplicationCommandOption::Type::SUB_COMMAND) {
522+
member.add_role(role);
523+
interaction.reply("role " + role.get_name() + " assigned to " + std::string(member));
524+
} else if (InteractionDataOptionHelper::get_interaction_data_option_name(option) == "remove" && InteractionDataOptionHelper::get_interaction_data_option_type(option) == ApplicationCommandOption::Type::SUB_COMMAND) {
525+
member.remove_role(role);
526+
interaction.reply("role " + role.get_name() + " removed from " + std::string(member));
527+
}
528+
}
484529
}
485530
}
486531

0 commit comments

Comments
 (0)