diff options
| author | soler_j <soler_j@etna-alternance.net> | 2025-05-04 02:19:10 +0200 |
|---|---|---|
| committer | soler_j <soler_j@etna-alternance.net> | 2025-05-04 02:19:10 +0200 |
| commit | 169e01b53d105cee6a9d32a466e1ec23fe150a5b (patch) | |
| tree | 4abbfde67e8925d47d8bc2a2eae8b606671c8a98 | |
| parent | e82d081f0fc630fe9244ff9d461f91dd1d4dc63b (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.json | 2 | ||||
| -rw-r--r-- | app/cmd/main.go | 30 | ||||
| -rw-r--r-- | app/internal/create_bot.go | 4 | ||||
| -rw-r--r-- | bot/include/actions/delete.hpp | 2 | ||||
| -rw-r--r-- | bot/include/handle_actions.hpp | 2 | ||||
| -rw-r--r-- | bot/src/actions/delete.cpp | 25 | ||||
| -rw-r--r-- | bot/src/handle_actions.cpp | 24 | ||||
| -rw-r--r-- | bot/src/main.cpp | 310 |
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); } |
