summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsoler_j <soler_j@etna-alternance.net>2025-05-04 02:19:10 +0200
committersoler_j <soler_j@etna-alternance.net>2025-05-04 02:19:10 +0200
commit169e01b53d105cee6a9d32a466e1ec23fe150a5b (patch)
tree4abbfde67e8925d47d8bc2a2eae8b606671c8a98
parente82d081f0fc630fe9244ff9d461f91dd1d4dc63b (diff)
Mise à jour de la configuration et amélioration de la gestion des actions :
- Changement du répertoire source CMake dans settings.json. - Ajout de la gestion des données et des intentions par défaut lors du démarrage du bot. - Modification des signatures des fonctions delete_action et handle_actions pour retourner des résultats plus détaillés. - Amélioration de la logique de réponse dans handle_actions pour gérer les erreurs et les succès.
-rw-r--r--.vscode/settings.json2
-rw-r--r--app/cmd/main.go30
-rw-r--r--app/internal/create_bot.go4
-rw-r--r--bot/include/actions/delete.hpp2
-rw-r--r--bot/include/handle_actions.hpp2
-rw-r--r--bot/src/actions/delete.cpp25
-rw-r--r--bot/src/handle_actions.cpp24
-rw-r--r--bot/src/main.cpp310
8 files changed, 252 insertions, 147 deletions
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 798eedd..42e44f8 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,5 +1,5 @@
{
- "cmake.sourceDirectory": "/Users/jeremy/Documents/bot-creator-api/bot",
+ "cmake.sourceDirectory": "/home/exa/perso/bot-creator-api/bot",
"files.associations": {
"map": "cpp",
"__bit_reference": "cpp",
diff --git a/app/cmd/main.go b/app/cmd/main.go
index 2232c8e..c42a013 100644
--- a/app/cmd/main.go
+++ b/app/cmd/main.go
@@ -69,8 +69,36 @@ func main() {
return
}
// let's check if the bot is already running
+ // let's parse the body.
+ var body map[string]interface{}
- bot, err = internal.Start(bot)
+ if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
+ log.Printf("[SERVER] Error decoding JSON: %v", err)
+ http.Error(w, "Invalid JSON", http.StatusBadRequest)
+ return
+ }
+
+ if body["intents"] == nil {
+ // intents are the default ones we can set the default ones
+ body["intents"] = "3243773"
+ }
+ if body["data"] == nil {
+ // data are the default ones we can set the default ones
+ fmt.Printf("[SERVER] No data found, setting default ones")
+ body["data"] = map[string]interface{}{}
+ }
+
+ // let's convert the data to a string
+ data, err := json.Marshal(body["data"])
+ if err != nil {
+ log.Printf("[SERVER] Error marshaling JSON: %v", err)
+ http.Error(w, "Error marshaling JSON", http.StatusInternalServerError)
+ return
+ }
+
+ fmt.Printf("[SERVER] Starting bot with data: %s", string(data))
+
+ bot, err = internal.Start(bot, string(data), fmt.Sprint(body["intents"]))
if err != nil {
log.Printf("[SERVER] Error starting bot: %v", err)
http.Error(w, "Error starting bot", http.StatusInternalServerError)
diff --git a/app/internal/create_bot.go b/app/internal/create_bot.go
index ce70cdd..ed4d59e 100644
--- a/app/internal/create_bot.go
+++ b/app/internal/create_bot.go
@@ -17,10 +17,10 @@ type Bot struct {
client *http.Client
}
-func Start(b *Bot) (*Bot, error) {
+func Start(b *Bot, data string, intents string) (*Bot, error) {
// Create a new ZeroMQ socket specifically for this bot
// Configuration du bot
- cmd := exec.Command("./discord-bot", b.BotToken, b.ProcessID) // Passer le port unique
+ cmd := exec.Command("./discord-bot", b.BotToken, b.ProcessID, data, intents)
cmd.SysProcAttr = &syscall.SysProcAttr{
Setpgid: true, // Permet de tuer le processus enfant si nécessaire
}
diff --git a/bot/include/actions/delete.hpp b/bot/include/actions/delete.hpp
index 8e4766e..bd582ec 100644
--- a/bot/include/actions/delete.hpp
+++ b/bot/include/actions/delete.hpp
@@ -1,3 +1,3 @@
#include <dpp/dpp.h>
-dpp::task<bool> delete_action(const dpp::slashcommand_t &event, const nlohmann::json &action, const std::unordered_map<std::string, std::string> &key_values, dpp::user &user_ptr, dpp::cluster *cluster);
+dpp::task<std::unordered_map<std::string, std::string>> delete_action(const dpp::slashcommand_t &event, const nlohmann::json &action, const std::unordered_map<std::string, std::string> &key_values, dpp::user &user_ptr, dpp::cluster *cluster);
diff --git a/bot/include/handle_actions.hpp b/bot/include/handle_actions.hpp
index 107e93d..c1dff78 100644
--- a/bot/include/handle_actions.hpp
+++ b/bot/include/handle_actions.hpp
@@ -1,3 +1,3 @@
#include <dpp/dpp.h>
-dpp::task<bool> handle_actions(const dpp::slashcommand_t& event, const nlohmann::json& actions, const std::unordered_map<std::string, std::string>& key_values);
+dpp::task<std::unordered_map<std::string, std::string>> handle_actions(const dpp::slashcommand_t& event, const nlohmann::json& actions, const std::unordered_map<std::string, std::string>& key_values);
diff --git a/bot/src/actions/delete.cpp b/bot/src/actions/delete.cpp
index da74bbf..d8748d2 100644
--- a/bot/src/actions/delete.cpp
+++ b/bot/src/actions/delete.cpp
@@ -1,4 +1,5 @@
#include "../../include/utils.hpp"
+#include <unordered_map>
const std::unordered_map<Lang, std::unordered_map<std::string, std::string>> error_messages_map = {
@@ -16,7 +17,7 @@ const std::unordered_map<Lang, std::unordered_map<std::string, std::string>> err
}}
};
-dpp::task<bool> delete_action(const dpp::slashcommand_t &event, const nlohmann::json &action,
+dpp::task<std::unordered_map<std::string, std::string>> delete_action(const dpp::slashcommand_t &event, const nlohmann::json &action,
const std::unordered_map<std::string, std::string> &key_values,
dpp::user &user_ptr, dpp::cluster *cluster)
{
@@ -51,14 +52,14 @@ dpp::task<bool> delete_action(const dpp::slashcommand_t &event, const nlohmann::
if (!member_ptr || !bot_member_ptr)
{
event.edit_response(error_messages.at("error_perm_channel"));
- co_return false;
+ co_return std::unordered_map<std::string, std::string>{{"error", error_messages.at("error_perm_channel")}};
}
const bool has_permissions = channel_ptr->get_user_permissions(*member_ptr).has(dpp::p_manage_messages) && channel_ptr->get_user_permissions(*bot_member_ptr).has(dpp::p_manage_messages);
if (!has_permissions)
{
event.edit_response(error_messages.at("error_perm_channel"));
- co_return false;
+ co_return std::unordered_map<std::string, std::string>{{"error", error_messages.at("error_perm_channel")}};
}
int amount = 0;
@@ -73,13 +74,13 @@ dpp::task<bool> delete_action(const dpp::slashcommand_t &event, const nlohmann::
if (amount < 1 || amount > 100)
{
event.edit_response(error_messages.at("error_amount"));
- co_return false;
+ co_return std::unordered_map<std::string, std::string>{{"error", error_messages.at("error_amount")}};
}
}
catch (const std::exception &e)
{
event.edit_response(error_messages.at("error"));
- co_return false;
+ co_return std::unordered_map<std::string, std::string>{{"error", error_messages.at("error")}};
}
}
}
@@ -92,14 +93,14 @@ dpp::task<bool> delete_action(const dpp::slashcommand_t &event, const nlohmann::
if (callback.is_error())
{
event.edit_response(error_messages.at("error"));
- co_return false;
+ co_return std::unordered_map<std::string, std::string>{{"error", error_messages.at("error")}};
}
const auto &messages = callback.get<dpp::message_map>();
if (messages.empty())
{
event.edit_response(error_messages.at("error_no_messages"));
- co_return false;
+ co_return std::unordered_map<std::string, std::string>{{"error", error_messages.at("error_no_messages")}};
}
std::vector<dpp::snowflake> msg_ids;
@@ -122,10 +123,16 @@ dpp::task<bool> delete_action(const dpp::slashcommand_t &event, const nlohmann::
if (delete_result.is_error())
{
event.edit_response(error_messages.at("error"));
- co_return false;
+ co_return std::unordered_map<std::string, std::string>{{"error", error_messages.at("error")}};
}
+ amount = msg_ids.size();
}
}
- co_return true;
+ std::string key = action.contains("key") ? action["key"] : "delete";
+
+ co_return std::unordered_map<std::string, std::string>{
+ {"success", "Messages deleted successfully."},
+ {key + ".amount", std::to_string(amount)},
+ };
}
diff --git a/bot/src/handle_actions.cpp b/bot/src/handle_actions.cpp
index 0b3f2ff..ef6e1c0 100644
--- a/bot/src/handle_actions.cpp
+++ b/bot/src/handle_actions.cpp
@@ -1,6 +1,7 @@
#include "../include/actions/delete.hpp"
-dpp::task<bool> handle_actions(const dpp::slashcommand_t &event, const nlohmann::json &actions, const std::unordered_map<std::string, std::string> &key_values)
+dpp::task<std::unordered_map<std::string, std::string>> handle_actions(const dpp::slashcommand_t &event, const nlohmann::json &actions, const std::unordered_map<std::string, std::string> &key_values)
{
+ std::unordered_map<std::string, std::string> workflow_key_values = {{}};
dpp::cluster *cluster = event.owner;
dpp::user user_ptr = event.command.get_issuing_user();
dpp::async thinking = event.co_thinking(false);
@@ -15,12 +16,23 @@ dpp::task<bool> handle_actions(const dpp::slashcommand_t &event, const nlohmann:
std::string action_type = action["type"];
if (action_type == "delete_messages" && event.command.is_guild_interaction())
{
- auto return_value = co_await delete_action(event, action, key_values, user_ptr, cluster);
+ std::unordered_map<std::string, std::string> return_value = co_await delete_action(event, action, key_values, user_ptr, cluster);
co_await thinking;
// if it's a false, we need to return false !
- if (!return_value)
+ if (return_value.contains("error"))
{
- co_return false;
+ co_return return_value;
+ }
+ else
+ {
+ // return everything expect the success message
+ for (const auto &[key, value] : return_value)
+ {
+ if (key != "success")
+ {
+ workflow_key_values[key] = value;
+ }
+ }
}
@@ -30,10 +42,10 @@ dpp::task<bool> handle_actions(const dpp::slashcommand_t &event, const nlohmann:
{
co_await thinking;
- co_return true;
+ co_return workflow_key_values;
}
}
}
co_await thinking;
- co_return true;
+ co_return workflow_key_values;
}
diff --git a/bot/src/main.cpp b/bot/src/main.cpp
index 1edac34..73bae00 100644
--- a/bot/src/main.cpp
+++ b/bot/src/main.cpp
@@ -1,140 +1,198 @@
-#include "../include/utils.hpp"
-#include "../include/http_webhook_server.hpp"
#include "../include/handle_actions.hpp"
+#include "../include/http_webhook_server.hpp"
+#include "../include/utils.hpp"
#include <thread>
-
-
-dpp::activity_type activity_type_from_string(const std::string& type) {
- if (type == "playing") {
- return dpp::activity_type::at_game;
- } else if (type == "streaming") {
- return dpp::activity_type::at_streaming;
- } else if (type == "listening") {
- return dpp::activity_type::at_listening;
- } else if (type == "watching") {
- return dpp::activity_type::at_watching;
- } else if (type == "custom") {
- return dpp::activity_type::at_custom;
- } else if (type == "competing") {
- return dpp::activity_type::at_competing;
- } else {
- return dpp::activity_type::at_game; // Default to "playing" if the type is unknown
- }
+#include <unordered_map>
+
+dpp::activity_type activity_type_from_string(const std::string &type) {
+ if (type == "playing") {
+ return dpp::activity_type::at_game;
+ } else if (type == "streaming") {
+ return dpp::activity_type::at_streaming;
+ } else if (type == "listening") {
+ return dpp::activity_type::at_listening;
+ } else if (type == "watching") {
+ return dpp::activity_type::at_watching;
+ } else if (type == "custom") {
+ return dpp::activity_type::at_custom;
+ } else if (type == "competing") {
+ return dpp::activity_type::at_competing;
+ } else {
+ return dpp::activity_type::at_game; // Default to "playing" if the type is
+ // unknown
+ }
}
-int main(int argc, char* argv[]) {
- if (argc > 2) {
- setenv("BOT_TOKEN", argv[1], 1);
- setenv("PORT", argv[2], 1);
+int main(int argc, char *argv[]) {
+ int intents = dpp::i_default_intents;
+ std::unique_ptr<nlohmann::json> json_data =
+ std::make_unique<nlohmann::json>();
+ if (argc > 2) {
+ setenv("BOT_TOKEN", argv[1], 1);
+ setenv("PORT", argv[2], 1);
+ if (argc > 3) {
+ json_data =
+ std::make_unique<nlohmann::json>(nlohmann::json::parse(argv[3]));
+ }
+ if (argc > 4) {
+ intents = std::stoi(argv[4]);
+ }
+ }
+
+ const std::string BOT_TOKEN = getenv("BOT_TOKEN");
+ const std::string PORT = getenv("PORT");
+ dpp::cluster bot(BOT_TOKEN, intents);
+
+ bot.on_log(dpp::utility::cout_logger());
+
+ bot.on_slashcommand([&json_data, &bot](
+ const dpp::slashcommand_t &event) -> dpp::task<void> {
+ std::unordered_map<std::string, std::string> key_values =
+ app::generate_key_values(event);
+ std::string command_name = event.command.get_command_name();
+ std::string response = "Interaction found, but no response found.";
+
+ if (!command_name.empty() && json_data->contains(command_name)) {
+ auto &command_data = (*json_data)[command_name];
+ if (command_data.contains("actions")) {
+ auto &action = command_data["actions"];
+ // Actions are a list of Objects
+ if (action.is_array()) {
+ std::cout << "Executing → Actions: " << action.dump() << std::endl;
+ std::unordered_map<std::string, std::string>
+ already_returned_message =
+ co_await handle_actions(event, action, key_values);
+ if (already_returned_message.contains("error")) {
+ std::cout << "Error: " << already_returned_message["error"]
+ << std::endl;
+ } else {
+ std::cout << "Actions executed successfully." << std::endl;
+ // let's push the values to the key_values
+ for (const auto &[key, value] : already_returned_message) {
+ if (key != "success") {
+ key_values[key] = value;
+ }
+ }
+ }
+ }
+ // let's retrieve final response.
+ response = command_data["response"];
+ auto update_response = app::update_string(response, key_values);
+ std::cout << "Executing → Response: " << update_response << std::endl;
+ co_return event.edit_response(update_response);
+ }
+ if (command_data.contains("response")) {
+ response = command_data["response"];
+ }
+ //
}
- const std::string BOT_TOKEN = getenv("BOT_TOKEN");
- const std::string PORT = getenv("PORT");
-
- dpp::cluster bot(BOT_TOKEN);
- std::unique_ptr<nlohmann::json> json_data = std::make_unique<nlohmann::json>();
-
- bot.on_log(dpp::utility::cout_logger());
-
- bot.on_slashcommand([&json_data, &bot](const dpp::slashcommand_t& event) -> dpp::task<void> {
- std::unordered_map<std::string, std::string> key_values = app::generate_key_values(event);
- std::string command_name = event.command.get_command_name();
- std::string response = "Interaction found, but no response found.";
-
- if (!command_name.empty() && json_data->contains(command_name)) {
- auto& command_data = (*json_data)[command_name];
- if (command_data.contains("actions")) {
- auto& action = command_data["actions"];
- // Actions are a list of Objects
- if (action.is_array()) {
- std::cout << "Executing → Actions: " << action.dump() << std::endl;
- auto already_returned_message = co_await handle_actions(event, action, key_values);
- if(!already_returned_message) {
- std::cout << "Command: " << command_name << " → Action: " << action.dump() << std::endl;
- co_return;
- }else {
- // This mean we need to edit the response, not reply
- if(command_data.contains("response")) {
- response = command_data["response"];
- std::cout << "Command: " << command_name << " → Response: " << response << std::endl;
- }
- event.edit_response(app::update_string(response, key_values));
- co_return;
+ auto update_response = app::update_string(response, key_values);
+ std::cout << "Executing → Response: " << update_response << std::endl;
+ co_return event.reply(update_response);
+ });
+
+ bot.on_ready([&bot, &json_data, &PORT](const dpp::ready_t &event) {
+ if (dpp::run_once<struct register_bot_commands>()) {
+ std::thread http_thread([&json_data, &PORT, &bot]() {
+ try {
+ HttpWebhookServer server(std::stoi(PORT), [&json_data, &bot](
+ const HttpWebhookServer::
+ HttpRequest &req) {
+ HttpWebhookServer::HttpResponse res;
+
+ if (req.method == "POST") {
+ res.status_code = 200;
+ res.headers["Content-Type"] = "application/json";
+
+ try {
+ nlohmann::json body_json = app::json_from_string(req.body);
+ res.body = R"({"received": "POST request received"})";
+
+ if (body_json.contains("command")) {
+ if (body_json["command"] == "update") {
+ json_data =
+ std::make_unique<nlohmann::json>(body_json["data"]);
+ } else if (body_json["command"] == "update_status") {
+ std::string status = body_json.contains("status")
+ ? body_json["status"]
+ : "online";
+ std::string activity = body_json.contains("activity")
+ ? body_json["activity"]
+ : "";
+ std::string activity_status =
+ body_json.contains("activity_status")
+ ? body_json["activity_status"]
+ : "";
+ std::string activity_url =
+ body_json.contains("activity_url")
+ ? body_json["activity_url"]
+ : "";
+ std::string activity_type =
+ body_json.contains("activity_type")
+ ? body_json["activity_type"]
+ : "playing";
+ dpp::presence p;
+ if (status == "online") {
+ p = dpp::presence(
+ dpp::presence_status::ps_online,
+ dpp::activity(
+ activity_type_from_string(activity_type),
+ activity, activity_status, activity_url));
+ } else if (status == "offline") {
+ p = dpp::presence(
+ dpp::presence_status::ps_offline,
+ dpp::activity(
+ activity_type_from_string(activity_type),
+ activity, activity_status, activity_url));
+ } else if (status == "dnd") {
+ p = dpp::presence(
+ dpp::presence_status::ps_dnd,
+ dpp::activity(
+ activity_type_from_string(activity_type),
+ activity, activity_status, activity_url));
+ } else if (status == "idle") {
+ p = dpp::presence(
+ dpp::presence_status::ps_idle,
+ dpp::activity(
+ activity_type_from_string(activity_type),
+ activity, activity_status, activity_url));
+ } else if (status == "invisible") {
+ p = dpp::presence(
+ dpp::presence_status::ps_invisible,
+ dpp::activity(
+ activity_type_from_string(activity_type),
+ activity, activity_status, activity_url));
}
+ bot.set_presence(p);
+ }
+ res.body =
+ R"({"status": "success", "message": "Command executed successfully"})";
}
+ } catch (const std::exception &e) {
+ res.status_code = 400;
+ res.body = std::string("{\"error\": \"") + e.what() + "\"}";
+ }
+ } else {
+ res.status_code = 400;
+ res.headers["Content-Type"] = "text/plain";
+ res.body = "Invalid request method.";
}
- if (command_data.contains("response")) {
- response = command_data["response"];
- std::cout << "Command: " << command_name << " → Response: " << response << std::endl;
- }
- }
-
- event.reply(app::update_string(response, key_values));
- });
-
- bot.on_ready([&bot, &json_data, &PORT](const dpp::ready_t& event) {
- if (dpp::run_once<struct register_bot_commands>()) {
- std::thread http_thread([&json_data, &PORT,&bot]() {
- try {
- HttpWebhookServer server(std::stoi(PORT), [&json_data, &bot](const HttpWebhookServer::HttpRequest& req) {
- HttpWebhookServer::HttpResponse res;
-
- if (req.method == "POST") {
- res.status_code = 200;
- res.headers["Content-Type"] = "application/json";
- try {
- nlohmann::json body_json = app::json_from_string(req.body);
- res.body = R"({"received": "POST request received"})";
+ return res;
+ });
- if (body_json.contains("command")) {
- if(body_json["command"] == "update"){
- json_data = std::make_unique<nlohmann::json>(body_json["data"]);
- }else if(body_json["command"] == "update_status"){
- std::string status = body_json.contains("status") ? body_json["status"] : "online";
- std::string activity = body_json.contains("activity") ? body_json["activity"] : "";
- std::string activity_status = body_json.contains("activity_status") ? body_json["activity_status"] : "";
- std::string activity_url = body_json.contains("activity_url") ? body_json["activity_url"] : "";
- std::string activity_type = body_json.contains("activity_type") ? body_json["activity_type"] : "playing";
- dpp::presence p;
- if (status == "online") {
- p = dpp::presence(dpp::presence_status::ps_online, dpp::activity(activity_type_from_string(activity_type), activity, activity_status, activity_url));
- } else if (status == "offline") {
- p = dpp::presence(dpp::presence_status::ps_offline, dpp::activity(activity_type_from_string(activity_type), activity, activity_status, activity_url));
- } else if (status == "dnd") {
- p = dpp::presence(dpp::presence_status::ps_dnd, dpp::activity(activity_type_from_string(activity_type), activity, activity_status, activity_url));
- } else if (status == "idle") {
- p = dpp::presence(dpp::presence_status::ps_idle, dpp::activity(activity_type_from_string(activity_type), activity, activity_status, activity_url));
- } else if (status == "invisible") {
- p = dpp::presence(dpp::presence_status::ps_invisible, dpp::activity(activity_type_from_string(activity_type), activity, activity_status, activity_url));
- }
- bot.set_presence(p);
- }
- res.body = R"({"status": "success", "message": "Command executed successfully"})";
- }
- } catch (const std::exception& e) {
- res.status_code = 400;
- res.body = std::string("{\"error\": \"") + e.what() + "\"}";
- }
- } else {
- res.status_code = 400;
- res.headers["Content-Type"] = "text/plain";
- res.body = "Invalid request method.";
- }
-
- return res;
- });
-
- std::cout << "[BOT] Webhook server running on port " << PORT << "..." << std::endl;
- server.start();
- } catch (const std::exception& e) {
- std::cerr << "[BOT] Server error: " << e.what() << std::endl;
- }
- });
-
- http_thread.detach();
+ std::cout << "[BOT] Webhook server running on port " << PORT << "..."
+ << std::endl;
+ server.start();
+ } catch (const std::exception &e) {
+ std::cerr << "[BOT] Server error: " << e.what() << std::endl;
}
- });
+ });
+
+ http_thread.detach();
+ }
+ });
- bot.start(dpp::st_wait);
+ bot.start(dpp::st_wait);
}