DiscordCoreAPI
A Discord bot library written in C++, with custom asynchronous coroutines.
Loading...
Searching...
No Matches
InteractionEntities.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/// InteractionEntities.cpp - Source file for the interaction_data related classes and structs.
27/// May 28, 2021
28/// https://discordcoreapi.com
29/// \file InteractionEntities.cpp
30
36
37namespace jsonifier {
38
39 template<> struct core<discord_core_api::interaction_callback_data> {
40 using value_type = discord_core_api::interaction_callback_data;
41 static constexpr auto parseValue = createValue("attachments", &value_type::attachments, "choices", &value_type::choices, "components", &value_type::components, "content",
42 &value_type::content, "custom_id", &value_type::customId, "embeds", &value_type::embeds, "flags", &value_type::flags, "tts",
43 &value_type::tts, "allowed_mentions", &value_type::allowedMentions, "title", &value_type::title);
44 };
45
46 template<> struct core<discord_core_api::interaction_response_base> {
47 using value_type = discord_core_api::interaction_response_base;
48 static constexpr auto parseValue = createValue("type", &value_type::type, "data", &value_type::data);
49 };
50
51 template<> struct core<discord_core_api::create_interaction_response_data> {
52 using value_type = discord_core_api::create_interaction_response_data;
53 static constexpr auto parseValue = createValue("type", &value_type::type, "data", &value_type::data);
54 };
55
56 template<> struct core<discord_core_api::edit_interaction_response_data> {
57 using value_type = discord_core_api::edit_interaction_response_data;
58 static constexpr auto parseValue = createValue("content", &value_type::content, "embeds", &value_type::embeds, "allowed_mentions", &value_type::allowedMentions,
59 "components", &value_type::components, "attachments", &value_type::attachments);
60 };
61
62 template<> struct core<discord_core_api::create_follow_up_message_data> {
63 using value_type = discord_core_api::create_follow_up_message_data;
64 static constexpr auto parseValue = createValue("content", &value_type::content, "username", &value_type::userName, "avatar_url", &value_type::avatarUrl, "tts",
65 &value_type::tts, "embeds", &value_type::embeds, "allowed_mentions", &value_type::allowedMentions, "components", &value_type::components,
66 "attachments", &value_type::attachments, "flags", &value_type::flags);
67 };
68
69 template<> struct core<discord_core_api::edit_follow_up_message_data> {
70 using value_type = discord_core_api::edit_follow_up_message_data;
71 static constexpr auto parseValue = createValue("content", &value_type::content, "username", &value_type::userName, "avatar_url", &value_type::avatarUrl, "tts",
72 &value_type::tts, "embeds", &value_type::embeds, "allowed_mentions", &value_type::allowedMentions, "components", &value_type::components,
73 "attachments", &value_type::attachments, "flags", &value_type::flags);
74 };
75
76}
77
78namespace discord_core_api {
79
80 interaction_response_base& interaction_response_base::addButton(bool disabled, jsonifier::string_view customIdNew, jsonifier::string_view buttonLabel, button_style buttonStyle,
81 jsonifier::string_view emojiName, snowflake emojiId, jsonifier::string_view url) {
82 if (data.components.size() == 0) {
83 action_row_data actionRowData;
84 data.components.emplace_back(actionRowData);
85 }
86 if (data.components.size() < 5) {
87 if (data.components[data.components.size() - 1].components.size() < 5) {
88 component_data component;
89 component.type = component_type::Button;
90 component.emoji.name = emojiName;
91 component.label = buttonLabel;
92 component.style = static_cast<uint64_t>(buttonStyle);
93 component.customId = customIdNew;
94 component.disabled = disabled;
95 component.emoji.id = emojiId;
96 component.url = url;
97 data.components[data.components.size() - 1].components.emplace_back(component);
98 } else if (data.components[data.components.size() - 1].components.size() == 5) {
99 action_row_data actionRowData;
100 data.components.emplace_back(actionRowData);
101 }
102 }
103 return *this;
104 }
105
106 interaction_response_base& interaction_response_base::addSelectMenu(bool disabled, jsonifier::string_view customIdNew, jsonifier::vector<select_option_data> options,
107 jsonifier::string_view placeholder, uint64_t maxValues, uint64_t minValues, select_menu_type typeNew, jsonifier::vector<channel_type> channelTypes) {
108 if (data.components.size() == 0) {
109 action_row_data actionRowData;
110 data.components.emplace_back(actionRowData);
111 }
112 if (data.components.size() < 5) {
113 if (data.components[data.components.size() - 1].components.size() < 5) {
114 component_data componentData;
115 componentData.type = static_cast<component_type>(typeNew);
116 componentData.channelTypes = channelTypes;
117 componentData.placeholder = placeholder;
118 componentData.customId = customIdNew;
119 componentData.maxValues = maxValues;
120 componentData.minValues = minValues;
121 componentData.disabled = disabled;
122 componentData.options = options;
123 data.components[data.components.size() - 1].components.emplace_back(componentData);
124 } else if (data.components[data.components.size() - 1].components.size() == 5) {
125 action_row_data actionRowData;
126 data.components.emplace_back(actionRowData);
127 }
128 }
129 return *this;
130 }
131
132 interaction_response_base& interaction_response_base::addModal(jsonifier::string_view topTitleNew, jsonifier::string_view topCustomIdNew, jsonifier::string_view titleNew,
133 jsonifier::string_view customIdNew, bool required, uint64_t minLength, uint64_t maxLength, text_input_style inputStyle, jsonifier::string_view label,
134 jsonifier::string_view placeholder) {
135 data.title = topTitleNew;
136 data.customId = topCustomIdNew;
137 if (data.components.size() == 0) {
138 action_row_data actionRowData;
139 data.components.emplace_back(actionRowData);
140 }
141 if (data.components.size() < 5) {
142 if (data.components[data.components.size() - 1].components.size() < 5) {
143 component_data component{};
144 component.type = component_type::Text_Input;
145 component.customId = customIdNew;
146 component.style = static_cast<uint64_t>(inputStyle);
147 component.title = titleNew;
148 component.maxLength = maxLength;
149 component.minLength = minLength;
150 component.label = label;
151 component.required = required;
152 component.placeholder = placeholder;
153 data.components[data.components.size() - 1].components.emplace_back(component);
154 } else if (data.components[data.components.size() - 1].components.size() == 5) {
155 action_row_data actionRowData;
156 data.components.emplace_back(actionRowData);
157 }
158 }
159 return *this;
160 }
161
162 interaction_response_base& interaction_response_base::addFile(const file& theFile) {
163 data.files.emplace_back(theFile);
164 return *this;
165 }
166
167 interaction_response_base& interaction_response_base::addAllowedMentions(const allowed_mentions_data dataPackage) {
168 data.allowedMentions = dataPackage;
169 return *this;
170 }
171
172 interaction_response_base& interaction_response_base::addComponentRow(const action_row_data dataPackage) {
173 data.components.emplace_back(dataPackage);
174 return *this;
175 }
176
177 interaction_response_base& interaction_response_base::setResponseType(interaction_callback_type typeNew) {
178 type = typeNew;
179 return *this;
180 }
181
182 void interaction_response_base::generateExcludedKeys() {
183 data.jsonifierExcludedKeys.clear();
184 data.generateExcludedKeys();
185 return;
186 }
187
188 interaction_response_base& interaction_response_base::addMessageEmbed(const embed_data dataPackage) {
189 data.embeds.emplace_back(dataPackage);
190 return *this;
191 }
192
193 interaction_response_base& interaction_response_base::addContent(jsonifier::string_view dataPackage) {
194 data.content = dataPackage;
195 return *this;
196 }
197
198 interaction_response_base& interaction_response_base::setTTSStatus(bool enabledTTs) {
199 data.tts = enabledTTs;
200 return *this;
201 }
202
203 interaction_response_base& interaction_response_base::setFlags(uint64_t flagsNew) {
204 data.flags = flagsNew;
205 return *this;
206 }
207
208 interaction_response_data interaction_response_base::getInteractionResponseData() {
209 interaction_response_data returnData;
210 returnData.data = data;
211 returnData.type = type;
212 return returnData;
213 }
214
215 void interactions::initialize(discord_core_internal::https_client* client) {
216 interactions::httpsClient = client;
217 }
218
219 create_ephemeral_interaction_response_data::create_ephemeral_interaction_response_data(const respond_to_input_event_data dataPackage) {
220 data = dataPackage;
221 if (dataPackage.eventType == interaction_type::Message_Component) {
223 } else {
225 }
226 interactionPackage.interactionToken = dataPackage.interactionToken;
227 interactionPackage.applicationId = dataPackage.applicationId;
228 interactionPackage.interactionId = dataPackage.interactionId;
229 data.flags = 64;
230 }
231
232 create_deferred_interaction_response_data::create_deferred_interaction_response_data(const respond_to_input_event_data dataPackage) {
233 data = dataPackage;
234 if (dataPackage.eventType == interaction_type::Message_Component) {
236 } else {
238 }
239 interactionPackage.interactionToken = dataPackage.interactionToken;
240 interactionPackage.applicationId = dataPackage.applicationId;
241 interactionPackage.interactionId = dataPackage.interactionId;
242 }
243
244 create_interaction_response_data::create_interaction_response_data(const create_deferred_interaction_response_data dataPackage) {
245 interactionPackage.interactionToken = dataPackage.interactionPackage.interactionToken;
246 interactionPackage.applicationId = dataPackage.interactionPackage.applicationId;
247 interactionPackage.interactionId = dataPackage.interactionPackage.interactionId;
248 data.components = dataPackage.data.components;
249 type = dataPackage.type;
250 data = dataPackage.data;
251 }
252
253 create_interaction_response_data::create_interaction_response_data(const create_ephemeral_interaction_response_data dataPackage) {
254 interactionPackage.interactionToken = dataPackage.interactionPackage.interactionToken;
255 interactionPackage.applicationId = dataPackage.interactionPackage.applicationId;
256 interactionPackage.interactionId = dataPackage.interactionPackage.interactionId;
257 data.components = dataPackage.data.components;
258 type = dataPackage.type;
259 data = dataPackage.data;
260 data.flags = 64;
261 }
262
263 create_interaction_response_data::create_interaction_response_data(const respond_to_input_event_data dataPackage) {
264 data = dataPackage;
265 if (dataPackage.eventType == interaction_type::Message_Component && dataPackage.type == input_event_response_type::Deferred_Response) {
267 } else if (dataPackage.eventType == interaction_type::Message_Component) {
269 } else if (dataPackage.eventType == interaction_type::Application_Command_Autocomplete ||
272 } else {
274 }
275 if (dataPackage.type == input_event_response_type::Modal_Interaction_Response || dataPackage.title != "") {
277 }
278 interactionPackage.interactionToken = dataPackage.interactionToken;
279 interactionPackage.applicationId = dataPackage.applicationId;
280 interactionPackage.interactionId = dataPackage.interactionId;
281 data.files = dataPackage.files;
282 }
283
284 create_interaction_response_data::create_interaction_response_data(const interaction_data dataPackage) {
285 if (dataPackage.type == interaction_type::Message_Component) {
287 } else {
289 }
290 interactionPackage.applicationId = dataPackage.applicationId;
291 interactionPackage.interactionToken = dataPackage.token;
292 interactionPackage.interactionId = dataPackage.id;
293 }
294
295 edit_interaction_response_data::edit_interaction_response_data(const respond_to_input_event_data dataPackage) {
296 interactionPackage.interactionToken = dataPackage.interactionToken;
297 interactionPackage.applicationId = dataPackage.applicationId;
298 interactionPackage.interactionId = dataPackage.interactionId;
299 allowedMentions = dataPackage.allowedMentions;
300 components = dataPackage.components;
301 content = dataPackage.content;
302 embeds = dataPackage.embeds;
303 title = dataPackage.title;
304 flags = dataPackage.flags;
305 files = dataPackage.files;
306 tts = dataPackage.tts;
307 }
308
309 create_ephemeral_follow_up_message_data::create_ephemeral_follow_up_message_data(const respond_to_input_event_data dataPackage) {
310 interactionPackage.interactionToken = dataPackage.interactionToken;
311 interactionPackage.applicationId = dataPackage.applicationId;
312 interactionPackage.interactionId = dataPackage.interactionId;
313 allowedMentions = dataPackage.allowedMentions;
314 components = dataPackage.components;
315 content = dataPackage.content;
316 embeds = dataPackage.embeds;
317 files = dataPackage.files;
318 tts = dataPackage.tts;
319 flags = 64;
320 }
321
322 create_follow_up_message_data::create_follow_up_message_data(const create_ephemeral_follow_up_message_data dataPackage) {
323 interactionPackage = dataPackage.interactionPackage;
324 allowedMentions = dataPackage.allowedMentions;
325 components = dataPackage.components;
326 content = dataPackage.content;
327 embeds = dataPackage.embeds;
328 flags = dataPackage.flags;
329 files = dataPackage.files;
330 tts = dataPackage.tts;
331 flags = 64;
332 }
333
334 create_follow_up_message_data::create_follow_up_message_data(const respond_to_input_event_data dataPackage) {
335 interactionPackage.interactionToken = dataPackage.interactionToken;
336 interactionPackage.applicationId = dataPackage.applicationId;
337 interactionPackage.interactionId = dataPackage.interactionId;
338 allowedMentions = dataPackage.allowedMentions;
339 components = dataPackage.components;
340 content = dataPackage.content;
341 embeds = dataPackage.embeds;
342 flags = dataPackage.flags;
343 files = dataPackage.files;
344 tts = dataPackage.tts;
345 }
346
347 edit_follow_up_message_data::edit_follow_up_message_data(const respond_to_input_event_data dataPackage) {
348 interactionPackage.interactionToken = dataPackage.interactionToken;
349 allowedMentions = dataPackage.allowedMentions;
350 interactionPackage.applicationId = dataPackage.applicationId;
351 interactionPackage.interactionId = dataPackage.interactionId;
352 messagePackage.channelId = dataPackage.channelId;
353 messagePackage.messageId = dataPackage.messageId;
354 components = dataPackage.components;
355 content = dataPackage.content;
356 embeds = dataPackage.embeds;
357 files = dataPackage.files;
358 }
359
360 delete_follow_up_message_data::delete_follow_up_message_data(const respond_to_input_event_data dataPackage) {
361 interactionPackage.interactionToken = dataPackage.interactionToken;
362 interactionPackage.applicationId = dataPackage.applicationId;
363 interactionPackage.interactionId = dataPackage.interactionId;
364 messagePackage.channelId = dataPackage.channelId;
365 messagePackage.messageId = dataPackage.messageId;
366 }
367
368 delete_interaction_response_data::delete_interaction_response_data(const respond_to_input_event_data dataPackage) {
369 interactionPackage.interactionToken = dataPackage.interactionToken;
370 interactionPackage.applicationId = dataPackage.applicationId;
371 interactionPackage.interactionId = dataPackage.interactionId;
372 }
373
375 discord_core_internal::https_workload_data workload{ discord_core_internal::https_workload_type::Post_Interaction_Response };
377 workload.workloadClass = discord_core_internal::https_workload_class::Post;
378 auto dataPackage{ dataPackageNew };
379 workload.relativePath = "/interactions/" + dataPackage.interactionPackage.interactionId + "/" + dataPackage.interactionPackage.interactionToken + "/callback";
380 dataPackage.generateExcludedKeys();
381 if (dataPackage.data.files.size() > 0) {
382 workload.payloadType = discord_core_internal::payload_type::Multipart_Form;
383 }
384 parser.serializeJson(dataPackage, workload.content);
385 workload.callStack = "interactions::createInteractionResponseAsync()";
386 interactions::httpsClient->submitWorkloadAndGetResult(std::move(workload));
387 get_interaction_response_data dataPackage01{};
388 dataPackage01.applicationId = dataPackage.interactionPackage.applicationId;
389 dataPackage01.interactionToken = dataPackage.interactionPackage.interactionToken;
391 co_return interactions::getInteractionResponseAsync(dataPackage01).get();
392 } else {
393 co_return message_data{};
394 }
395 }
396
397 message_data interactions::getInteractionResponse(get_interaction_response_data dataPackage) {
398 discord_core_internal::https_workload_data workload{ discord_core_internal::https_workload_type::Get_Interaction_Response };
399 workload.workloadClass = discord_core_internal::https_workload_class::Get;
400 workload.relativePath = "/webhooks/" + dataPackage.applicationId + "/" + dataPackage.interactionToken + "/messages/@original";
401 workload.callStack = "interactions::getInteractionResponseAsync()";
402 message_data returnData{};
403 interactions::httpsClient->submitWorkloadAndGetResult(std::move(workload), returnData);
404 return returnData;
405 }
406
407
409 discord_core_internal::https_workload_data workload{ discord_core_internal::https_workload_type::Get_Interaction_Response };
411 workload.workloadClass = discord_core_internal::https_workload_class::Get;
412 workload.relativePath = "/webhooks/" + dataPackage.applicationId + "/" + dataPackage.interactionToken + "/messages/@original";
413 workload.callStack = "interactions::getInteractionResponseAsync()";
414 message_data returnData{};
415 interactions::httpsClient->submitWorkloadAndGetResult(std::move(workload), returnData);
416 co_return returnData;
417 }
418
420 discord_core_internal::https_workload_data workload{ discord_core_internal::https_workload_type::Patch_Interaction_Response };
422 auto dataPackage{ dataPackageNew };
423 workload.workloadClass = discord_core_internal::https_workload_class::Patch;
424 workload.relativePath = "/webhooks/" + dataPackage.interactionPackage.applicationId + "/" + dataPackage.interactionPackage.interactionToken + "/messages/@original";
425 dataPackage.generateExcludedKeys();
426 if (dataPackage.files.size() > 0) {
427 workload.payloadType = discord_core_internal::payload_type::Multipart_Form;
428 }
429 parser.serializeJson(dataPackage, workload.content);
430 workload.callStack = "interactions::editInteractionResponseAsync()";
431 message_data returnData{};
432 interactions::httpsClient->submitWorkloadAndGetResult(std::move(workload), returnData);
433 co_return returnData;
434 }
435
437 discord_core_internal::https_workload_data workload{ discord_core_internal::https_workload_type::Delete_Interaction_Response };
438 co_await newThreadAwaitable<void>();
439 std::this_thread::sleep_for(milliseconds{ dataPackage.timeDelay });
440 workload.workloadClass = discord_core_internal::https_workload_class::Delete;
441 workload.relativePath = "/webhooks/" + dataPackage.interactionPackage.applicationId + "/" + dataPackage.interactionPackage.interactionToken + "/messages/@original";
442 workload.callStack = "interactions::deleteInteractionResponseAsync()";
443 interactions::httpsClient->submitWorkloadAndGetResult(std::move(workload));
444 co_return;
445 }
446
448 discord_core_internal::https_workload_data workload{ discord_core_internal::https_workload_type::Post_Followup_Message };
450 auto dataPackage{ dataPackageNew };
451 workload.workloadClass = discord_core_internal::https_workload_class::Post;
452 workload.relativePath = "/webhooks/" + dataPackage.interactionPackage.applicationId + "/" + dataPackage.interactionPackage.interactionToken;
453 dataPackage.generateExcludedKeys();
454 if (dataPackage.files.size() > 0) {
455 workload.payloadType = discord_core_internal::payload_type::Multipart_Form;
456 }
457 parser.serializeJson(dataPackage, workload.content);
458 workload.callStack = "interactions::createFollowUpMessageAsync()";
459 message_data returnData{};
460 interactions::httpsClient->submitWorkloadAndGetResult(std::move(workload), returnData);
461 co_return returnData;
462 }
463
465 discord_core_internal::https_workload_data workload{ discord_core_internal::https_workload_type::Get_Followup_Message };
467 workload.workloadClass = discord_core_internal::https_workload_class::Get;
468 workload.relativePath = "/webhooks/" + dataPackage.applicationId + "/" + dataPackage.interactionToken + "/messages/" + dataPackage.messageId;
469 workload.callStack = "interactions::getFollowUpMessageAsync()";
470 message_data returnData{};
471 interactions::httpsClient->submitWorkloadAndGetResult(std::move(workload), returnData);
472 co_return returnData;
473 }
474
476 discord_core_internal::https_workload_data workload{ discord_core_internal::https_workload_type::Patch_Followup_Message };
478 auto dataPackage{ dataPackageNew };
479 workload.workloadClass = discord_core_internal::https_workload_class::Patch;
480 workload.relativePath = "/webhooks/" + dataPackage.interactionPackage.applicationId + "/" + dataPackage.interactionPackage.interactionToken + "/messages/" +
481 dataPackage.messagePackage.messageId;
482 dataPackage.generateExcludedKeys();
483 if (dataPackage.files.size() > 0) {
484 workload.payloadType = discord_core_internal::payload_type::Multipart_Form;
485 }
486 parser.serializeJson(dataPackage, workload.content);
487 workload.callStack = "interactions::editFollowUpMessageAsync()";
488 message_data returnData{};
489 interactions::httpsClient->submitWorkloadAndGetResult(std::move(workload), returnData);
490 co_return returnData;
491 }
492
494 discord_core_internal::https_workload_data workload{ discord_core_internal::https_workload_type::Delete_Followup_Message };
495 co_await newThreadAwaitable<void>();
496 std::this_thread::sleep_for(milliseconds{ dataPackage.timeDelay });
497 workload.workloadClass = discord_core_internal::https_workload_class::Delete;
498 workload.relativePath = "/webhooks/" + dataPackage.interactionPackage.applicationId + "/" + dataPackage.interactionPackage.interactionToken + "/messages/" +
499 dataPackage.messagePackage.messageId;
500 workload.callStack = "interactions::deleteFollowUpMessageAsync()";
501 interactions::httpsClient->submitWorkloadAndGetResult(std::move(workload));
502 co_return;
503 }
504
505 message_data interactions::createInteractionResponse(create_interaction_response_data dataPackageNew) {
506 discord_core_internal::https_workload_data workload{ discord_core_internal::https_workload_type::Post_Interaction_Response };
507 workload.workloadClass = discord_core_internal::https_workload_class::Post;
508 auto dataPackage{ dataPackageNew };
509 workload.relativePath = "/interactions/" + dataPackage.interactionPackage.interactionId + "/" + dataPackage.interactionPackage.interactionToken + "/callback";
510 dataPackage.generateExcludedKeys();
511 if (dataPackage.data.files.size() > 0) {
512 workload.payloadType = discord_core_internal::payload_type::Multipart_Form;
513 }
514 parser.serializeJson(dataPackage, workload.content);
515 workload.callStack = "interactions::createInteractionResponse()";
516 interactions::httpsClient->submitWorkloadAndGetResult(std::move(workload));
517 get_interaction_response_data dataPackage01{};
518 dataPackage01.applicationId = dataPackage.interactionPackage.applicationId;
519 dataPackage01.interactionToken = dataPackage.interactionPackage.interactionToken;
521 return interactions::getInteractionResponse(dataPackage01);
522 } else {
523 return {};
524 }
525 }
526
527 message_data interactions::editInteractionResponse(edit_interaction_response_data dataPackageNew) {
528 discord_core_internal::https_workload_data workload{ discord_core_internal::https_workload_type::Patch_Interaction_Response };
529 auto dataPackage{ dataPackageNew };
530 workload.workloadClass = discord_core_internal::https_workload_class::Patch;
531 workload.relativePath = "/webhooks/" + dataPackage.interactionPackage.applicationId + "/" + dataPackage.interactionPackage.interactionToken + "/messages/@original";
532 dataPackage.generateExcludedKeys();
533 if (dataPackage.files.size() > 0) {
534 workload.payloadType = discord_core_internal::payload_type::Multipart_Form;
535 }
536 parser.serializeJson(dataPackage, workload.content);
537 workload.callStack = "interactions::editInteractionResponse()";
538 message_data returnData{};
539 interactions::httpsClient->submitWorkloadAndGetResult(std::move(workload), returnData);
540 return returnData;
541 }
542
543 message_data interactions::createFollowUpMessage(create_follow_up_message_data dataPackageNew) {
544 auto dataPackage{ dataPackageNew };
545 discord_core_internal::https_workload_data workload{ discord_core_internal::https_workload_type::Post_Followup_Message };
546 workload.workloadClass = discord_core_internal::https_workload_class::Post;
547 workload.relativePath = "/webhooks/" + dataPackage.interactionPackage.applicationId + "/" + dataPackage.interactionPackage.interactionToken;
548 dataPackage.generateExcludedKeys();
549 if (dataPackage.files.size() > 0) {
550 workload.payloadType = discord_core_internal::payload_type::Multipart_Form;
551 }
552 parser.serializeJson(dataPackage, workload.content);
553 workload.callStack = "interactions::createFollowUpMessage()";
554 message_data returnData{};
555 interactions::httpsClient->submitWorkloadAndGetResult(std::move(workload), returnData);
556 return returnData;
557 }
558
559 message_data interactions::editFollowUpMessage(edit_follow_up_message_data dataPackageNew) {
560 auto dataPackage{ dataPackageNew };
561 discord_core_internal::https_workload_data workload{ discord_core_internal::https_workload_type::Patch_Followup_Message };
562 workload.workloadClass = discord_core_internal::https_workload_class::Patch;
563 workload.relativePath = "/webhooks/" + dataPackage.interactionPackage.applicationId + "/" + dataPackage.interactionPackage.interactionToken + "/messages/" +
564 dataPackage.messagePackage.messageId;
565 dataPackage.generateExcludedKeys();
566 if (dataPackage.files.size() > 0) {
567 workload.payloadType = discord_core_internal::payload_type::Multipart_Form;
568 }
569 parser.serializeJson(dataPackage, workload.content);
570 workload.callStack = "interactions::editFollowUpMessage()";
571 message_data returnData{};
572 interactions::httpsClient->submitWorkloadAndGetResult(std::move(workload), returnData);
573 return returnData;
574 }
575
577 channelId = dataPackage.getInteractionData().channelId;
578 messageId = dataPackage.getMessageData().id;
579 *interactionData = dataPackage.getInteractionData();
580 buffersMapKey = channelId.operator jsonifier::string() + messageId.operator jsonifier::string();
581 }
582
583 co_routine<jsonifier::vector<select_menu_response_data>, false> select_menu_collector::collectSelectMenuData(bool getSelectMenuDataForAllNew, uint32_t maxWaitTimeInMsNew,
584 uint32_t maxCollectedSelectMenuCountNew, create_interaction_response_data errorMessageDataNew, snowflake targetUser) {
586 select_menu_collector::selectMenuInteractionBuffersMap[buffersMapKey] = &selectMenuIncomingInteractionBuffer;
587 if (targetUser == 0 && !getSelectMenuDataForAllNew) {
588 getSelectMenuDataForAll = true;
589 } else {
590 getSelectMenuDataForAll = getSelectMenuDataForAllNew;
591 }
592 if (targetUser != 0) {
593 userId = targetUser;
594 }
595 maxCollectedSelectMenuCount = maxCollectedSelectMenuCountNew;
596 getSelectMenuDataForAll = getSelectMenuDataForAllNew;
597 errorMessageData = errorMessageDataNew;
598 maxTimeInMs = maxWaitTimeInMsNew;
599 run();
600 co_return std::move(responseVector);
601 }
602
603 void select_menu_collector::collectSelectMenuData(std::function<bool(interaction_data)> triggerFunctionNew,
605 functionNew.setTestFunction(triggerFunctionNew);
606 select_menu_collector::selectMenuInteractionEventsMap.add(std::move(functionNew));
607 }
608
609 select_menu_collector::~select_menu_collector() {
610 if (select_menu_collector::selectMenuInteractionBuffersMap.contains(buffersMapKey)) {
611 select_menu_collector::selectMenuInteractionBuffersMap.erase(buffersMapKey);
612 }
613 }
614
615 void select_menu_collector::run() {
616 stop_watch<milliseconds> stopWatch{ milliseconds{ maxTimeInMs } };
617 stopWatch.reset();
618 while (!doWeQuit && !stopWatch.hasTimeElapsed()) {
619 if (!getSelectMenuDataForAll) {
620 auto selectMenuInteractionData = makeUnique<interaction_data>();
621 if (waitForTimeToPass(selectMenuIncomingInteractionBuffer, *selectMenuInteractionData.get(), maxTimeInMs)) {
622 selectMenuId = "empty";
624 response->selectionId = selectMenuId;
625 response->channelId = channelId;
626 response->messageId = messageId;
627 response->userId = selectMenuInteractionData->user.id;
628 *response->interactionData = *interactionData;
629 response->values = jsonifier::vector<jsonifier::string>{ "empty" };
630 responseVector.emplace_back(*response);
631 break;
632 }
633 if (selectMenuInteractionData->member.user.id != userId) {
634 errorMessageData.interactionPackage.applicationId = selectMenuInteractionData->applicationId;
635 errorMessageData.interactionPackage.interactionId = selectMenuInteractionData->id;
636 errorMessageData.interactionPackage.interactionToken = selectMenuInteractionData->token;
637 errorMessageData.messagePackage.messageId = selectMenuInteractionData->message.id;
638 errorMessageData.messagePackage.channelId = selectMenuInteractionData->message.channelId;
640 interactions::createInteractionResponseAsync(errorMessageData).get();
641 } else {
642 *interactionData = *selectMenuInteractionData;
643 selectMenuId = selectMenuInteractionData->data.customId;
645 response->selectionId = selectMenuId;
646 response->channelId = channelId;
647 response->messageId = messageId;
648 response->userId = selectMenuInteractionData->user.id;
649 response->values = interactionData->data.values;
650 *response->interactionData = *selectMenuInteractionData;
651 responseVector.emplace_back(*response);
652 ++currentCollectedSelectMenuCount;
653 stopWatch.reset();
654 if (maxCollectedSelectMenuCount > 1 && currentCollectedSelectMenuCount < maxCollectedSelectMenuCount - 1) {
655 auto createResponseData = makeUnique<create_interaction_response_data>(*selectMenuInteractionData);
657 interactions::createInteractionResponseAsync(*createResponseData).get();
658 }
659 if (currentCollectedSelectMenuCount >= maxCollectedSelectMenuCount) {
660 for (auto& value: responseVector) {
661 *value.interactionData = *selectMenuInteractionData;
662 }
663 doWeQuit = true;
664 }
665 }
666 } else {
667 auto selectMenuInteractionData = makeUnique<interaction_data>();
668 if (waitForTimeToPass(selectMenuIncomingInteractionBuffer, *selectMenuInteractionData.get(), maxTimeInMs)) {
669 selectMenuId = "empty";
671 response->selectionId = selectMenuId;
672 response->channelId = channelId;
673 response->messageId = messageId;
674 response->userId = selectMenuInteractionData->user.id;
675 *response->interactionData = *interactionData;
676 response->values = jsonifier::vector<jsonifier::string>{ "empty" };
677 responseVector.emplace_back(*response);
678 break;
679 }
680 *interactionData = *selectMenuInteractionData;
681 selectMenuId = selectMenuInteractionData->data.customId;
683 response->selectionId = selectMenuId;
684 response->channelId = channelId;
685 response->messageId = messageId;
686 response->userId = selectMenuInteractionData->user.id;
687 *response->interactionData = *selectMenuInteractionData;
688 response->values = interactionData->data.values;
689 responseVector.emplace_back(*response);
690 ++currentCollectedSelectMenuCount;
691 stopWatch.reset();
692 if (maxCollectedSelectMenuCount > 1 && currentCollectedSelectMenuCount < maxCollectedSelectMenuCount - 1) {
693 auto createResponseData = makeUnique<create_interaction_response_data>(*selectMenuInteractionData);
695 interactions::createInteractionResponseAsync(*createResponseData).get();
696 }
697 if (currentCollectedSelectMenuCount >= maxCollectedSelectMenuCount) {
698 doWeQuit = true;
699 for (auto& value: responseVector) {
700 *value.interactionData = *selectMenuInteractionData;
701 }
702 }
703 }
704 std::this_thread::sleep_for(1ms);
705 }
706 select_menu_collector::selectMenuInteractionBuffersMap.erase(buffersMapKey);
707 }
708
710 channelId = dataPackage.getInteractionData().channelId;
711 messageId = dataPackage.getMessageData().id;
712 *interactionData = dataPackage.getInteractionData();
713 buffersMapKey = channelId.operator jsonifier::string() + messageId.operator jsonifier::string();
714 button_collector::buttonInteractionBuffersMap[buffersMapKey] = &buttonIncomingInteractionBuffer;
715 }
716
717 co_routine<jsonifier::vector<button_response_data>, false> button_collector::collectButtonData(bool getButtonDataForAllNew, uint32_t maxWaitTimeInMsNew,
718 uint32_t maxNumberOfPressesNew, create_interaction_response_data errorMessageDataNew, snowflake targetUser) {
720 if (targetUser == 0 && !getButtonDataForAllNew) {
721 throw dca_exception{ "button_collector::collectButtonData(), you've failed to "
722 "properly set the collectButtonData() parameters!" };
723 }
724 if (targetUser != 0) {
725 userId = targetUser;
726 }
727 maxCollectedButtonCount = maxNumberOfPressesNew;
728 getButtonDataForAll = getButtonDataForAllNew;
729 errorMessageData = errorMessageDataNew;
730 maxTimeInMs = maxWaitTimeInMsNew;
731 run();
732 co_return std::move(responseVector);
733 }
734
735 void button_collector::collectButtonData(std::function<bool(interaction_data)> triggerFunctionNew,
737 functionNew.setTestFunction(triggerFunctionNew);
738 button_collector::buttonInteractionEventsMap.add(std::move(functionNew));
739 }
740
741 button_collector::~button_collector() {
742 if (button_collector::buttonInteractionBuffersMap.contains(buffersMapKey)) {
743 button_collector::buttonInteractionBuffersMap.erase(buffersMapKey);
744 }
745 }
746
747 void button_collector::run() {
748 stop_watch<milliseconds> stopWatch{ milliseconds{ maxTimeInMs } };
749 stopWatch.reset();
750 while (!doWeQuit && !stopWatch.hasTimeElapsed()) {
751 if (!getButtonDataForAll) {
752 auto buttonInteractionData = makeUnique<interaction_data>();
753 if (waitForTimeToPass(buttonIncomingInteractionBuffer, *buttonInteractionData.get(), maxTimeInMs)) {
754 buttonId = "empty";
755 auto response = makeUnique<button_response_data>();
756 response->buttonId = buttonId;
757 response->channelId = channelId;
758 response->messageId = messageId;
759 response->userId = buttonInteractionData->user.id;
760 *response->interactionData = *interactionData;
761 responseVector.emplace_back(*response);
762 break;
763 }
764 if (buttonInteractionData->member.user.id != userId) {
765 errorMessageData.interactionPackage.applicationId = buttonInteractionData->applicationId;
766 errorMessageData.interactionPackage.interactionId = buttonInteractionData->id;
767 errorMessageData.interactionPackage.interactionToken = buttonInteractionData->token;
768 errorMessageData.messagePackage.messageId = buttonInteractionData->message.id;
769 errorMessageData.messagePackage.channelId = buttonInteractionData->message.channelId;
771 interactions::createInteractionResponseAsync(errorMessageData).get();
772 } else {
773 *interactionData = *buttonInteractionData;
774 buttonId = buttonInteractionData->data.customId;
775 auto response = makeUnique<button_response_data>();
776 response->buttonId = buttonId;
777 response->channelId = channelId;
778 response->messageId = messageId;
779 response->emojiName = buttonInteractionData->message.components[0].components[0].emoji.name;
780 response->userId = buttonInteractionData->user.id;
781 *response->interactionData = *buttonInteractionData;
782 responseVector.emplace_back(*response);
783 ++currentCollectedButtonCount;
784 stopWatch.reset();
785 if (maxCollectedButtonCount > 1 && currentCollectedButtonCount < maxCollectedButtonCount) {
786 auto createResponseData = makeUnique<create_interaction_response_data>(*buttonInteractionData);
788 interactions::createInteractionResponseAsync(*createResponseData).get();
789 }
790 if (currentCollectedButtonCount >= maxCollectedButtonCount) {
791 for (auto& value: responseVector) {
792 *value.interactionData = *buttonInteractionData;
793 }
794 doWeQuit = true;
795 }
796 }
797 } else {
798 auto buttonInteractionData = makeUnique<interaction_data>();
799 if (waitForTimeToPass(buttonIncomingInteractionBuffer, *buttonInteractionData.get(), maxTimeInMs)) {
800 buttonId = "empty";
801 auto response = makeUnique<button_response_data>();
802 response->buttonId = buttonId;
803 response->channelId = channelId;
804 response->messageId = messageId;
805 response->emojiName = buttonInteractionData->message.components[0].components[0].emoji.name;
806 response->userId = buttonInteractionData->user.id;
807 *response->interactionData = *buttonInteractionData;
808 responseVector.emplace_back(*response);
809 break;
810 }
811 *interactionData = *buttonInteractionData;
812 buttonId = buttonInteractionData->data.customId;
813 auto response = makeUnique<button_response_data>();
814 response->buttonId = buttonId;
815 response->channelId = channelId;
816 response->messageId = messageId;
817 response->emojiName = buttonInteractionData->message.components[0].components[0].emoji.name;
818 response->userId = buttonInteractionData->user.id;
819 *response->interactionData = *buttonInteractionData;
820 responseVector.emplace_back(*response);
821 ++currentCollectedButtonCount;
822 stopWatch.reset();
823 if (maxCollectedButtonCount > 1 && currentCollectedButtonCount < maxCollectedButtonCount) {
824 auto createResponseData = makeUnique<create_interaction_response_data>(*buttonInteractionData);
826 interactions::createInteractionResponseAsync(*createResponseData).get();
827 }
828 if (currentCollectedButtonCount >= maxCollectedButtonCount) {
829 for (auto& value: responseVector) {
830 *value.interactionData = *buttonInteractionData;
831 }
832 doWeQuit = true;
833 }
834 }
835 std::this_thread::sleep_for(1ms);
836 }
837 button_collector::buttonInteractionBuffersMap.erase(buffersMapKey);
838 }
839
841 channelId = dataPackage.getInteractionData().channelId;
842 modal_collector::modalInteractionBuffersMap[channelId.operator jsonifier::string()] = &modalIncomingInteractionBuffer;
843 }
844
847 maxTimeInMs = maxWaitTimeInMsNew;
848 run();
849 co_return std::move(responseData);
850 }
851
852 void modal_collector::collectModalData(std::function<bool(interaction_data)> triggerFunctionNew,
854 functionNew.setTestFunction(triggerFunctionNew);
855 modal_collector::modalInteractionEventsMap.add(std::move(functionNew));
856 }
857
858 modal_collector::~modal_collector() {
859 if (modal_collector::modalInteractionBuffersMap.contains(channelId.operator jsonifier::string())) {
860 modal_collector::modalInteractionBuffersMap.erase(channelId.operator jsonifier::string());
861 }
862 }
863
864 void modal_collector::run() {
865 stop_watch<milliseconds> stopWatch{ milliseconds{ maxTimeInMs } };
866 stopWatch.reset();
867 while (!doWeQuit && !stopWatch.hasTimeElapsed()) {
868 auto buttonInteractionData = makeUnique<interaction_data>();
869 if (waitForTimeToPass(modalIncomingInteractionBuffer, *buttonInteractionData.get(), maxTimeInMs)) {
870 *responseData.interactionData = *buttonInteractionData;
871 responseData.channelId = buttonInteractionData->channelId;
872 responseData.customId = buttonInteractionData->data.customId;
873 responseData.userId = buttonInteractionData->user.id;
874 responseData.values = buttonInteractionData->data.values;
875 break;
876 } else {
877 *responseData.interactionData = *buttonInteractionData;
878 responseData.channelId = buttonInteractionData->channelId;
879 responseData.customId = buttonInteractionData->data.customId;
880 responseData.userId = buttonInteractionData->user.id;
881 responseData.values = buttonInteractionData->data.values;
882 break;
883 }
884 }
885
886 modal_collector::modalInteractionBuffersMap.erase(channelId.operator jsonifier::string());
887 }
888
889 unordered_map<jsonifier::string, unbounded_message_block<interaction_data>*> select_menu_collector::selectMenuInteractionBuffersMap{};
890 unordered_map<jsonifier::string, unbounded_message_block<interaction_data>*> button_collector::buttonInteractionBuffersMap{};
891 unordered_map<jsonifier::string, unbounded_message_block<interaction_data>*> modal_collector::modalInteractionBuffersMap{};
892 discord_core_internal::trigger_event<void, interaction_data> select_menu_collector::selectMenuInteractionEventsMap{};
893 discord_core_internal::trigger_event<void, interaction_data> button_collector::buttonInteractionEventsMap{};
894 discord_core_internal::trigger_event<void, interaction_data> modal_collector::modalInteractionEventsMap{};
895 discord_core_internal::https_client* interactions::httpsClient{};
896};
Action row data of message components.
Allowable mentions for a message.
button_collector(input_event_data dataPackage)
Constructor.
co_routine< jsonifier::vector< button_response_data >, false > collectButtonData(bool getButtonDataForAllNew, uint32_t maxWaitTimeInMsNew, uint32_t maxNumberOfPressesNew, create_interaction_response_data errorMessageDataNew, snowflake targetUserId=snowflake{})
Used to collect the button inputs from one or more users.
A co_routine - representing a potentially asynchronous operation/function.
For creating an ephemeral follow up message_data.
For creating an ephemeral interaction response.
Event-delegate, for representing an event-function to be executed conditionally.
DCA_INLINE void setTestFunction(std::function< bool(arg_types...)> testFunctionNew)
Sets the test function to determine conditional execution.
A trigger event that fires based on the result of trigger-function return value.
For editing a follow up message_data.
allowed_mentions_data allowedMentions
Allowed mention object.
jsonifier::vector< embed_data > embeds
Array of up to 10 embed objects.
jsonifier::string content
The message contents (up to 2000 characters) one of content, file, embeds.
uint64_t flags
Flags combined as a bitfield.
jsonifier::string title
Title for the modal.
jsonifier::vector< file > files
File contents the contents of the file being sent.
jsonifier::vector< action_row_data > components
Array of message component the components to include with the message.
bool tts
True if this is a tts message.
Data representing an input-event, which is any message or interaction that is coming into the bot as ...
const interaction_data & getInteractionData() const
Returns the interaction data, if appplicable, of this input-event.
const message_data & getMessageData() const
Returns the message data, if applicable, of this input-event.
static co_routine< message_data > createFollowUpMessageAsync(create_follow_up_message_data dataPackage)
Creates a follow up message to an input interaction.
static co_routine< void > deleteFollowUpMessageAsync(delete_follow_up_message_data dataPackage)
Deletes a follow up message_data.
static co_routine< message_data > getFollowUpMessageAsync(get_follow_up_message_data dataPackage)
Creates a follow up message to an input interaction.
static co_routine< message_data > getInteractionResponseAsync(get_interaction_response_data dataPackage)
Collects an interaction response.
static co_routine< message_data > editInteractionResponseAsync(edit_interaction_response_data dataPackage)
Edits an interaction response.
static co_routine< message_data > editFollowUpMessageAsync(edit_follow_up_message_data dataPackage)
Edits a follow up message_data.
static co_routine< void > deleteInteractionResponseAsync(delete_interaction_response_data dataPackage)
Deletes an interaction respnose.
static co_routine< message_data > createInteractionResponseAsync(create_interaction_response_data dataPackage)
Creates a response to an input interaction.
The core of a message's data structure.
modal_collector(input_event_data dataPackage)
Constructor.
co_routine< modal_response_data, false > collectModalData(uint32_t maxWaitTimeInMsNew)
Used to collect the button inputs from one or more users.
Data for responding to an input-event.
select_menu_collector(input_event_data dataPackage)
Constructor.
co_routine< jsonifier::vector< select_menu_response_data >, false > collectSelectMenuData(bool getSelectMenuDataForAllNew, uint32_t maxWaitTimeInMsNew, uint32_t maxCollectedSelectMenuCountNew, create_interaction_response_data errorMessageDataNew, snowflake targetUserId=snowflake{})
Used to collect the select-menu inputs from one or more users.
A class representing a snowflake identifier with various operations.
Definition Base.hpp:701
interaction_callback_type
Interaction callback types.
text_input_style
Text input style for modals.
component_type
Component types.
@ Modal_Interaction_Response
Respond to an interaction with a popup modal.
@ Application_Command_AutoComplete_Result
Respond to an autocomplete interaction with suggested choices.
@ Deferred_Channel_Message_With_Source
Ack an interaction and edit a response later, the user sees a loading state.
@ Channel_Message_With_Source
Respond to an interaction with a message.
@ Deferred_Update_Message
For components, ack an interaction and edit the original message later; the user does not see a loadi...
@ Modal
Respond to an interaction with a popup modal.
@ Application_Command_Autocomplete_Result
Respond to an autocomplete interaction with suggested choices.
@ Update_Message
For components, edit the message the component was attached to.
@ Application_Command_Autocomplete
Application command autocomplete.
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...
DCA_INLINE unique_ptr< value_type, deleter > makeUnique(arg_types &&... args)
Helper function to create a unique_ptr for a non-array object.
The main namespace for the forward-facing interfaces.
Data representing a file to be sent via multipart-form data.
For getting a follow-up message_data.
jsonifier::string interactionToken
Interaction token.
jsonifier::string interactionToken
Interaction token.
interaction_callback_data data
Interaction application_command_data callback data.