DiscordCoreAPI
A Discord bot library written in C++, with custom asynchronous coroutines.
Loading...
Searching...
No Matches
ReactionEntities.cpp
Go to the documentation of this file.
1/*
2 MIT License
3
4 DiscordCoreAPI, A bot library for Discord, written in C++, and featuring explicit multithreading through the usage of custom, asynchronous C++ CoRoutines.
5
6 Copyright 2022, 2023 Chris M. (RealTimeChris)
7
8 Permission is hereby granted, free of charge, to any person obtaining a copy
9 of this software and associated documentation files (the "Software"), to deal
10 in the Software without restriction, including without limitation the rights
11 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 copies of the Software, and to permit persons to whom the Software is
13 furnished to do so, subject to the following conditions:
14
15 The above copyright notice and this permission notice shall be included in all
16 copies or substantial portions of the Software.
17
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 SOFTWARE.
25*/
26/// ReactionEntities.cpp - Source file for the reaction related classes and structs.
27/// May 13, 2021
28/// https://discordcoreapi.com
29/// \file ReactionEntities.cpp
30
35#include <fstream>
36
37namespace jsonifier {
38
39 template<> struct core<discord_core_api::create_guild_emoji_data> {
40 using value_type = discord_core_api::create_guild_emoji_data;
41 static constexpr auto parseValue = createValue("roles", &value_type::roles, "image", &value_type::imageDataFinal, "guildId",
42 &value_type::guildId, "name", &value_type::name, "type", &value_type::type);
43 };
44
45 template<> struct core<discord_core_api::modify_guild_emoji_data> {
46 using value_type = discord_core_api::modify_guild_emoji_data;
47 static constexpr auto parseValue =
48 createValue("roles", &value_type::roles, "guildId", &value_type::guildId, "emojiId", &value_type::emojiId, "name", &value_type::name);
49 };
50
51}
52
53namespace discord_core_api {
54
55 template<> unordered_map<jsonifier::string, unbounded_message_block<reaction_data>*> object_collector<reaction_data>::objectsBuffersMap{};
56
57 template<> object_collector<reaction_data>::object_collector() {
58 collectorId = jsonifier::toString(std::chrono::duration_cast<milliseconds>(sys_clock::now().time_since_epoch()).count());
59 object_collector::objectsBuffersMap[collectorId] = &objectsBuffer;
60 };
61
62 template<> void object_collector<reaction_data>::run(
63 std::coroutine_handle<typename discord_core_api::co_routine<discord_core_api::object_collector<discord_core_api::reaction_data>::object_collector_return_data,
64 false>::promise_type>& coroHandle) {
65 int64_t startingTime = static_cast<int64_t>(std::chrono::duration_cast<milliseconds>(sys_clock::now().time_since_epoch()).count());
66 int64_t elapsedTime{};
67 while (elapsedTime < msToCollectFor && !coroHandle.promise().stopRequested()) {
68 reaction_data message{};
69 waitForTimeToPass<reaction_data>(objectsBuffer, message, static_cast<uint64_t>(msToCollectFor - static_cast<uint64_t>(elapsedTime)));
70 if (filteringFunction(message)) {
71 objectReturnData.objects.emplace_back(message);
72 }
73 if (static_cast<int32_t>(objectReturnData.objects.size()) >= quantityOfObjectsToCollect) {
74 break;
75 }
76
77 elapsedTime = std::chrono::duration_cast<milliseconds>(sys_clock::now().time_since_epoch()).count() - startingTime;
78 }
79 }
80
82 int32_t msToCollectForNew, object_filter<reaction_data> filteringFunctionNew) {
84 quantityOfObjectsToCollect = quantityToCollect;
85 filteringFunction = filteringFunctionNew;
86 msToCollectFor = msToCollectForNew;
87
88 run(coroHandle);
89 co_return std::move(objectReturnData);
90 }
91
92 template<> object_collector<reaction_data>::~object_collector() {
93 if (object_collector::objectsBuffersMap.contains(collectorId)) {
94 object_collector::objectsBuffersMap.erase(collectorId);
95 }
96 };
97
98 void reactions::initialize(discord_core_internal::https_client* client) {
99 reactions::httpsClient = client;
100 }
101
103 discord_core_internal::https_workload_data workload{ discord_core_internal::https_workload_type::Put_Reaction };
105 jsonifier::string emoji;
106 if (dataPackage.emojiId != 0) {
107 emoji += ":" + dataPackage.emojiName + ":" + dataPackage.emojiId;
108 } else {
109 emoji = dataPackage.emojiName;
110 }
111 workload.workloadClass = discord_core_internal::https_workload_class::Put;
112 workload.relativePath = "/channels/" + dataPackage.channelId + "/messages/" + dataPackage.messageId + "/reactions/" + urlEncode(emoji) + "/@me";
113 workload.callStack = "reactions::createReactionAsync()";
114 reaction_data returnData{};
115 reactions::httpsClient->submitWorkloadAndGetResult(std::move(workload), returnData);
116 co_return returnData;
117 }
118
120 discord_core_internal::https_workload_data workload{ discord_core_internal::https_workload_type::Delete_Own_Reaction };
121 co_await newThreadAwaitable<void>();
122 jsonifier::string emoji;
123 if (dataPackage.emojiId != 0) {
124 emoji += ":" + dataPackage.emojiName + ":" + dataPackage.emojiId;
125 } else {
126 emoji = dataPackage.emojiName;
127 }
128 workload.workloadClass = discord_core_internal::https_workload_class::Delete;
129 workload.relativePath = "/channels/" + dataPackage.channelId + "/messages/" + dataPackage.messageId + "/reactions/" + urlEncode(emoji) + "/@me";
130 workload.callStack = "reactions::deleteOwnReactionAsync()";
131 reactions::httpsClient->submitWorkloadAndGetResult(std::move(workload));
132 co_return;
133 }
134
136 discord_core_internal::https_workload_data workload{ discord_core_internal::https_workload_type::Delete_User_Reaction };
137 co_await newThreadAwaitable<void>();
138 jsonifier::string emoji;
139 if (dataPackage.emojiId != 0) {
140 emoji += ":" + dataPackage.emojiName + ":" + dataPackage.emojiId;
141
142 } else {
143 emoji = dataPackage.emojiName;
144 }
145 workload.workloadClass = discord_core_internal::https_workload_class::Delete;
146 workload.relativePath = "/channels/" + dataPackage.channelId + "/messages/" + dataPackage.messageId + "/reactions/" + urlEncode(emoji) + "/" + dataPackage.userId;
147 workload.callStack = "reactions::deleteUserReactionAsync()";
148 reactions::httpsClient->submitWorkloadAndGetResult(std::move(workload));
149 co_return;
150 }
151
153 discord_core_internal::https_workload_data workload{ discord_core_internal::https_workload_type::Get_Reactions };
155 workload.workloadClass = discord_core_internal::https_workload_class::Get;
156 workload.relativePath = "/channels/" + dataPackage.channelId + "/messages/" + dataPackage.messageId + "/reactions/" + dataPackage.emoji;
157 if (dataPackage.afterId != 0) {
158 workload.relativePath += "?after=" + dataPackage.afterId;
159 if (dataPackage.limit != 0) {
160 workload.relativePath += "&limit=" + jsonifier::toString(dataPackage.limit);
161 }
162 } else if (dataPackage.limit != 0) {
163 workload.relativePath += "?limit=" + jsonifier::toString(dataPackage.limit);
164 }
165 workload.callStack = "reactions::getReactionsAsync()";
166 jsonifier::vector<user_data> returnData{};
167 reactions::httpsClient->submitWorkloadAndGetResult(std::move(workload), returnData);
168 co_return returnData;
169 }
170
171
173 discord_core_internal::https_workload_data workload{ discord_core_internal::https_workload_type::Delete_All_Reactions };
174 co_await newThreadAwaitable<void>();
175 workload.workloadClass = discord_core_internal::https_workload_class::Delete;
176 workload.relativePath = "/channels/" + dataPackage.channelId + "/messages/" + dataPackage.messageId + "/reactions";
177 workload.callStack = "reactions::deleteAllReactionsAsync()";
178 reactions::httpsClient->submitWorkloadAndGetResult(std::move(workload));
179 co_return;
180 }
181
183 discord_core_internal::https_workload_data workload{ discord_core_internal::https_workload_type::Delete_Reactions_By_Emoji };
184 co_await newThreadAwaitable<void>();
185 jsonifier::string emoji;
186 if (dataPackage.emojiId != 0) {
187 emoji += ":" + dataPackage.emojiName + ":" + dataPackage.emojiId;
188 } else {
189 emoji = dataPackage.emojiName;
190 }
191 workload.workloadClass = discord_core_internal::https_workload_class::Delete;
192 workload.relativePath = "/channels/" + dataPackage.channelId + "/messages/" + dataPackage.messageId + "/reactions/" + urlEncode(emoji);
193 workload.callStack = "reactions::deleteReactionsByEmojiAsync()";
194 reactions::httpsClient->submitWorkloadAndGetResult(std::move(workload));
195 co_return;
196 }
197
199 discord_core_internal::https_workload_data workload{ discord_core_internal::https_workload_type::Get_Emoji_List };
201 workload.workloadClass = discord_core_internal::https_workload_class::Get;
202 workload.relativePath = "/guilds/" + dataPackage.guildId + "/emojis";
203 workload.callStack = "reactions::getEmojiListAsync()";
204 jsonifier::vector<emoji_data> returnData{};
205 reactions::httpsClient->submitWorkloadAndGetResult(std::move(workload), returnData);
206 co_return returnData;
207 }
208
210 discord_core_internal::https_workload_data workload{ discord_core_internal::https_workload_type::Get_Guild_Emoji };
212 workload.workloadClass = discord_core_internal::https_workload_class::Get;
213 workload.relativePath = "/guilds/" + dataPackage.guildId + "/emojis/" + dataPackage.emojiId;
214 workload.callStack = "reactions::getGuildEmojiAsync()";
215 emoji_data returnData{};
216 reactions::httpsClient->submitWorkloadAndGetResult(std::move(workload), returnData);
217 co_return returnData;
218 }
219
221 discord_core_internal::https_workload_data workload{ discord_core_internal::https_workload_type::Post_Guild_Emoji };
223 workload.workloadClass = discord_core_internal::https_workload_class::Post;
224 jsonifier::string newerFile = base64Encode(loadFileContents(dataPackage.imageFilePath));
225 switch (dataPackage.type) {
226 case image_type::jpg: {
227 dataPackage.imageDataFinal = "data:image/jpeg;base64,";
228 dataPackage.imageDataFinal.insert(dataPackage.imageDataFinal.end(), newerFile.begin(), newerFile.end());
229 break;
230 }
231 case image_type::png: {
232 dataPackage.imageDataFinal = "data:image/png;base64,";
233 dataPackage.imageDataFinal.insert(dataPackage.imageDataFinal.end(), newerFile.begin(), newerFile.end());
234 break;
235 }
236 case image_type::gif: {
237 dataPackage.imageDataFinal = "data:image/gif;base64,";
238 dataPackage.imageDataFinal.insert(dataPackage.imageDataFinal.end(), newerFile.begin(), newerFile.end());
239 break;
240 }
241 }
242 workload.relativePath = "/guilds/" + dataPackage.guildId + "/emojis";
243 parser.serializeJson(dataPackage, workload.content);
244 workload.callStack = "reactions::createGuildEmojiAsync()";
245 if (dataPackage.reason != "") {
246 workload.headersToInsert["x-audit-log-reason"] = dataPackage.reason;
247 }
248 emoji_data returnData{};
249 reactions::httpsClient->submitWorkloadAndGetResult(std::move(workload), returnData);
250 co_return returnData;
251 }
252
254 discord_core_internal::https_workload_data workload{ discord_core_internal::https_workload_type::Patch_Guild_Emoji };
256 workload.workloadClass = discord_core_internal::https_workload_class::Patch;
257 workload.relativePath = "/guilds/" + dataPackage.guildId + "/emojis/" + dataPackage.emojiId;
258 parser.serializeJson(dataPackage, workload.content);
259 workload.callStack = "reactions::modifyGuildEmojiAsync()";
260 if (dataPackage.reason != "") {
261 workload.headersToInsert["x-audit-log-reason"] = dataPackage.reason;
262 }
263 emoji_data returnData{};
264 reactions::httpsClient->submitWorkloadAndGetResult(std::move(workload), returnData);
265 co_return returnData;
266 }
267
269 discord_core_internal::https_workload_data workload{ discord_core_internal::https_workload_type::Delete_Guild_Emoji };
270 co_await newThreadAwaitable<void>();
271 workload.workloadClass = discord_core_internal::https_workload_class::Delete;
272 workload.relativePath = "/guilds/" + dataPackage.guildId + "/emojis/" + dataPackage.emojiId;
273 workload.callStack = "reactions::deleteGuildEmojiAsync()";
274 if (dataPackage.reason != "") {
275 workload.headersToInsert["x-audit-log-reason"] = dataPackage.reason;
276 }
277 reactions::httpsClient->submitWorkloadAndGetResult(std::move(workload));
278 co_return;
279 }
280
281 discord_core_internal::https_client* reactions::httpsClient{};
282}
A co_routine - representing a potentially asynchronous operation/function.
co_routine< object_collector_return_data, false > collectObjects(int32_t quantityToCollect, int32_t msToCollectForNew, object_filter< value_type > filteringFunctionNew)
Begin waiting for objects.
/// data structure representing a single reaction.
static co_routine< void > deleteUserReactionAsync(delete_user_reaction_data dataPackage)
Deletes all of the reactions by a specific user_data from a given message_data.
static co_routine< jsonifier::vector< emoji_data > > getEmojiListAsync(get_emoji_list_data dataPackage)
Collects a list of guild emoji from a chosen guild.
static co_routine< void > deleteAllReactionsAsync(delete_all_reactions_data dataPackage)
Deletes all of the reactions from a given message_data.
static co_routine< void > deleteOwnReactionAsync(delete_own_reaction_data dataPackage)
Deletes your own reactions from a given message_data.
static co_routine< emoji_data > createGuildEmojiAsync(create_guild_emoji_data dataPackage)
Creates a single guild emoji within a chosen guild.
static co_routine< void > deleteReactionsByEmojiAsync(delete_reactions_by_emoji_data dataPackage)
Deletes all of the reactions by a specific emoji from a given message_data.
static co_routine< emoji_data > getGuildEmojiAsync(get_guild_emoji_data dataPackage)
Collects a single guild emoji from a chosen guild.
static co_routine< jsonifier::vector< user_data > > getReactionsAsync(get_reactions_data dataPackage)
Get a list of users that reacted with this emoji. returns An array of user objects on success.
static co_routine< reaction_data > createReactionAsync(create_reaction_data dataPackage)
Creates a reaction_data on a message.
static co_routine< emoji_data > modifyGuildEmojiAsync(modify_guild_emoji_data dataPackage)
Modifies a single guild emoji within a chosen guild.
static co_routine< void > deleteGuildEmojiAsync(delete_guild_emoji_data dataPackage)
Deletes a single guild emoji within a chosen guild.
std::function< bool(value_type)> object_filter
Typedef for the message filter.
DCA_INLINE auto newThreadAwaitable()
An awaitable that can be used to launch the co_routine onto a new thread - as well as return the hand...
The main namespace for the forward-facing interfaces.
snowflake guildId
The guild within which to create the emoji.
jsonifier::string reason
Reason for creating the new emoji.
image_type type
The type of image being uploaded.
jsonifier::string imageFilePath
The image responseData.
For creating a single reaction_data.
snowflake emojiId
The emoji id of the reaction_data to add.
snowflake messageId
The message on which to add the reaction_data.
jsonifier::string emojiName
The emoji name of the reaction_data to add.
snowflake channelId
The channel_data for which to add the reaction_data.
For deleting all of the reactions on a particular message_data.
snowflake channelId
The channel_data from which you would like to remove the emoji.
snowflake messageId
The message from which you would like to remove the emoji.
jsonifier::string reason
Reason for deleting the emoji.
snowflake guildId
The guild within which to delete the emoji.
snowflake emojiId
The id of the emoji to delete.
For deleting one's own reaction_data.
snowflake messageId
The message from which to remove the reaction_data.
jsonifier::string emojiName
The emoji name for which to remove the emoji.
snowflake channelId
The channel_data from which to remove the reaction_data.
snowflake emojiId
The emoji id for which to remove the emoji.
For deleting all of the reactions of a particular emoji.
snowflake emojiId
The id of which emoji to remove.
snowflake messageId
The message from which you would like to remove the emoji.
snowflake channelId
The channel_data from which you would like to remove the emoji.
jsonifier::string emojiName
The name of which emoji to remove.
For deleting a reaction, by user_data.
snowflake emojiId
The id of which emoji to remove.
snowflake messageId
The message from which to remove the reaction_data.
snowflake channelId
The channel_data from which to remove the reaction_data.
jsonifier::string emojiName
The name of which emoji to remove.
snowflake userId
The user_data id for whom to remove their emoji.
for collecting a list of emoji from a guild.
snowflake guildId
The id of the chosen guild.
for collecting a single guild emoji.
snowflake guildId
The id of the chosen guild.
snowflake emojiId
The id of the chosen emoji.
For getting all of the reactions.
snowflake messageId
The message from which to acquire the reactors.
snowflake channelId
The channel_data from which to acquire the reactors.
int32_t limit
The maximum number of reactors to collect.
jsonifier::string emoji
The emoji name for which to acquire the reactors.
snowflake afterId
Get users after this user id.
jsonifier::string reason
Reason for modifying the emoji.
snowflake guildId
The guild within which to modify the emoji.
snowflake emojiId
The id of the emoji to modify.