From c981f4e36780c583556c03fc56fe43c0830f982e Mon Sep 17 00:00:00 2001 From: soler_j Date: Sun, 4 May 2025 03:40:38 +0200 Subject: Ajout de la gestion des variables d'environnement pour la connexion à la base de données et mise à jour des fichiers de configuration pour inclure .env et .envrc. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .dockerignore | 1 + .envrc | 1 - .gitignore | 1 + app/cmd/main.go | 179 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ app/go.mod | 15 ++++- app/go.sum | 37 ++++++++++++ devenv.nix | 1 + 7 files changed, 233 insertions(+), 2 deletions(-) diff --git a/.dockerignore b/.dockerignore index f041403..2e81c06 100644 --- a/.dockerignore +++ b/.dockerignore @@ -22,3 +22,4 @@ CMakeFiles/ cmake-build-*/ Makefile CMakeCache.txt +.env diff --git a/.envrc b/.envrc index 30da14f..fb1924b 100644 --- a/.envrc +++ b/.envrc @@ -1,5 +1,4 @@ export DIRENV_WARN_TIMEOUT=20s - eval "$(devenv direnvrc)" use devenv diff --git a/.gitignore b/.gitignore index 0deb2c8..e5c1f77 100644 --- a/.gitignore +++ b/.gitignore @@ -36,6 +36,7 @@ devenv.local.nix # direnv .direnv +.env # pre-commit .pre-commit-config.yaml diff --git a/app/cmd/main.go b/app/cmd/main.go index c42a013..3c1e9e2 100644 --- a/app/cmd/main.go +++ b/app/cmd/main.go @@ -1,6 +1,7 @@ package main import ( + "context" "encoding/json" "fmt" "log" @@ -9,13 +10,44 @@ import ( "os/signal" "syscall" + "github.com/arangodb/go-driver/v2/arangodb" + "github.com/arangodb/go-driver/v2/connection" "github.com/ketsuna-org/bot-creator-api/internal" ) var botList = make(map[string]*internal.Bot) +var database arangodb.Database func init() { // Initialisation de l'application + password := os.Getenv("DB_PASSWORD") + user := os.Getenv("DB_USERNAME") + host := os.Getenv("DB_HOST") + dbName := os.Getenv("DB_NAME") + if password == "" || user == "" || host == "" || dbName == "" { + // display which env variable is missing + array := []string{"DB_PASSWORD", "DB_USERNAME", "DB_HOST", "DB_NAME"} + for _, v := range array { + if os.Getenv(v) == "" { + log.Printf("[SERVER] %s is missing", v) + } + } + } + + // Connexion à la base de données + conn := arangodb.NewClient(connection.NewHttp2Connection(connection.Http2Configuration{ + Endpoint: connection.NewRoundRobinEndpoints([]string{ + fmt.Sprintf("https://%s", host), + }), + Authentication: connection.NewBasicAuth(user, password), + })) + + db, err := conn.GetDatabase(context.Background(), dbName, nil) + if err != nil { + log.Fatalf("Failed to open database: %v", err) + } + + database = db } func main() { @@ -40,6 +72,15 @@ func main() { ProcessID: fmt.Sprint(len(botList) + 5555), // or any unique identifier } + // let's start the bot + col, err := database.GetCollection(context.Background(), "bots", nil) + if err != nil { + log.Printf("[SERVER] Error getting collection: %v", err) + http.Error(w, "Error getting collection", http.StatusInternalServerError) + return + } + // let's check if the bot already exists + // Let's check if this discord bot exists if _, ok := botList[botToken]; ok { log.Printf("[SERVER] Bot already running: %s", botToken) @@ -68,6 +109,42 @@ func main() { http.Error(w, "Bot not found", http.StatusNotFound) return } + + var botData map[string]interface{} + if err := json.NewDecoder(resp.Body).Decode(&botData); err != nil { + log.Printf("[SERVER] Error decoding JSON: %v", err) + http.Error(w, "Error decoding JSON", http.StatusInternalServerError) + return + } + + botData["_key"] = botData["id"] + id := botData["id"].(string) + botData["token"] = botToken + exist, err := col.DocumentExists(context.Background(), id) + if err != nil { + log.Printf("[SERVER] Error checking document: %v", err) + http.Error(w, "Error checking document", http.StatusInternalServerError) + return + } + + if !exist { // let's create the bot + _, err = col.CreateDocument(context.Background(), botData) + if err != nil { + log.Printf("[SERVER] Error creating bot: %v", err) + http.Error(w, "Error creating document", http.StatusInternalServerError) + return + } + log.Printf("[SERVER] Bot created: %s", botToken) + } else { + // let's update the bot + _, err = col.UpdateDocument(context.Background(), botData["id"].(string), botData) + if err != nil { + log.Printf("[SERVER] Error updating document: %v", err) + http.Error(w, "Error updating document", http.StatusInternalServerError) + return + } + log.Printf("[SERVER] Bot updated: %s", botToken) + } // let's check if the bot is already running // let's parse the body. var body map[string]interface{} @@ -86,6 +163,108 @@ func main() { // 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{}{} + } else { + // let's create each commands associated with the bot, and it's corresponding commands ID + // let's check if the data is a map + dataToUse, ok := body["data"].(map[string]interface{}) + if !ok { + log.Printf("[SERVER] Data is not a map") + http.Error(w, "Data is not a map", http.StatusBadRequest) + return + } + // let's check if the data is a map + // each command is a key. and the value is a map + for key, value := range dataToUse { + // let's check if the value is a map + valueToUse, ok := value.(map[string]interface{}) + if !ok { + log.Printf("[SERVER] Value is not a map") + http.Error(w, "Value is not a map", http.StatusBadRequest) + return + } + + valueToUse["_key"] = key + + col, err := database.GetCollection(context.Background(), "commands", nil) + // let's check if the name is set + if err != nil { + log.Printf("[SERVER] Error getting collection: %v", err) + http.Error(w, "Error getting collection", http.StatusInternalServerError) + return + } + + // first check if the command already exists + exist, err := col.DocumentExists(context.Background(), key) + if err != nil { + log.Printf("[SERVER] Error checking document: %v", err) + http.Error(w, "Error checking document", http.StatusInternalServerError) + return + } + if !exist { + // this mean we can create the command + // let's create the command + _, err = col.CreateDocument(context.Background(), valueToUse) + if err != nil { + log.Printf("[SERVER] Error creating document: %v", err) + http.Error(w, "Error creating document", http.StatusInternalServerError) + return + } + log.Printf("[SERVER] Command created: %s", key) + } else { + // let's update the command + _, err = col.UpdateDocument(context.Background(), key, valueToUse) + if err != nil { + log.Printf("[SERVER] Error updating document: %v", err) + http.Error(w, "Error updating document", http.StatusInternalServerError) + return + } + log.Printf("[SERVER] Command updated: %s", key) + } + + // let's create edge or update the edge + edgeCol, err := database.GetCollection(context.Background(), "bots_commands", nil) + if err != nil { + log.Printf("[SERVER] Error getting collection: %v", err) + http.Error(w, "Error getting collection", http.StatusInternalServerError) + return + } + // let's check if the edge already exists + edgeID := fmt.Sprintf("%s_%s", id, key) + exist, err = edgeCol.DocumentExists(context.Background(), edgeID) + if err != nil { + log.Printf("[SERVER] Error checking document: %v", err) + http.Error(w, "Error checking document", http.StatusInternalServerError) + return + } + + if !exist { + edge := map[string]interface{}{ + "_from": "bots/" + id, + "_to": "commands/" + key, + "_key": edgeID, + } + _, err = edgeCol.CreateDocument(context.Background(), edge) + if err != nil { + log.Printf("[SERVER] Error creating document: %v", err) + http.Error(w, "Error creating document", http.StatusInternalServerError) + return + } + log.Printf("[SERVER] Edge created: %s", edgeID) + } else { + // let's update the edge + edge := map[string]interface{}{ + "_from": "bots/" + id, + "_to": "commands/" + key, + } + _, err = edgeCol.UpdateDocument(context.Background(), edgeID, edge) + if err != nil { + log.Printf("[SERVER] Error updating document: %v", err) + http.Error(w, "Error updating document", http.StatusInternalServerError) + return + } + log.Printf("[SERVER] Edge updated: %s", edgeID) + } + } } // let's convert the data to a string diff --git a/app/go.mod b/app/go.mod index 0fdbadd..2e86acd 100644 --- a/app/go.mod +++ b/app/go.mod @@ -2,4 +2,17 @@ module github.com/ketsuna-org/bot-creator-api go 1.23.3 -require github.com/arangodb/go-driver/v2 v2.1.3 // indirect +require ( + github.com/arangodb/go-driver/v2 v2.1.3 // indirect + github.com/arangodb/go-velocypack v0.0.0-20200318135517-5af53c29c67e // indirect + github.com/dchest/siphash v1.2.3 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/kkdai/maglev v0.2.0 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/rs/zerolog v1.33.0 // indirect + golang.org/x/net v0.33.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/text v0.21.0 // indirect +) diff --git a/app/go.sum b/app/go.sum index b8dd409..b206855 100644 --- a/app/go.sum +++ b/app/go.sum @@ -1,6 +1,43 @@ github.com/arangodb/go-driver/v2 v2.1.3 h1:PpLSe8E2RalFuqTGi2yfHDe3ltOomfFCIToB66p1lr8= github.com/arangodb/go-driver/v2 v2.1.3/go.mod h1:aoDzrsO7PQEFat3Q9pp4zfv6W+WotA7GcCeJQJfX+tc= +github.com/arangodb/go-velocypack v0.0.0-20200318135517-5af53c29c67e h1:Xg+hGrY2LcQBbxd0ZFdbGSyRKTYMZCfBbw/pMJFOk1g= +github.com/arangodb/go-velocypack v0.0.0-20200318135517-5af53c29c67e/go.mod h1:mq7Shfa/CaixoDxiyAAc5jZ6CVBAyPaNQCGS7mkj4Ho= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dchest/siphash v1.2.2/go.mod h1:q+IRvb2gOSrUnYoPqHiyHXS0FOBBOdl6tONBlVnOnt4= +github.com/dchest/siphash v1.2.3 h1:QXwFc8cFOR2dSa/gE6o/HokBMWtLUaNDVd+22aKHeEA= +github.com/dchest/siphash v1.2.3/go.mod h1:0NvQU092bT0ipiFN++/rXm69QG9tVxLAlQHIXMPAkHc= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/kkdai/maglev v0.2.0 h1:w6DCW0kAA6fstZqXkrBrlgIC3jeIRXkjOYea/m6EK/Y= +github.com/kkdai/maglev v0.2.0/go.mod h1:d+mt8Lmt3uqi9aRb/BnPjzD0fy+ETs1vVXiGRnqHVZ4= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/pebbe/zmq4 v1.3.1 h1:WmGnjErIFjb43M6hq5nB/g9cUx9YQAXurAwfZV2Cgeo= github.com/pebbe/zmq4 v1.3.1/go.mod h1:nqnPueOapVhE2wItZ0uOErngczsJdLOGkebMxaO8r48= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= +github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= +golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/zeromq/goczmq.v4 v4.1.0 h1:CE+FE81mGVs2aSlnbfLuS1oAwdcVywyMM2AC1g33imI= gopkg.in/zeromq/goczmq.v4 v4.1.0/go.mod h1:h4IlfePEYMpFdywGr5gAwKhBBj+hiBl/nF4VoSE4k+0= diff --git a/devenv.nix b/devenv.nix index 5eb179d..2fd9a4b 100644 --- a/devenv.nix +++ b/devenv.nix @@ -1,6 +1,7 @@ { pkgs, lib, config, inputs, ... }: { + dotenv.enable = true; env = { CXXFLAGS = "-std=c++20"; PKG_CONFIG_PATH = "${pkgs.openssl.dev}/lib/pkgconfig"; # Critical pour trouver OpenSSL -- cgit v1.2.3