diff options
| author | soler_j <soler_j@etna-alternance.net> | 2025-04-29 03:57:44 +0200 | 
|---|---|---|
| committer | soler_j <soler_j@etna-alternance.net> | 2025-04-29 03:57:44 +0200 | 
| commit | 6ccd5f23c68bf6d8eb212e4c0cb3b887fff993a8 (patch) | |
| tree | 04ce0804bb914764751c5c5fc278282267368760 /app | |
| parent | e3a3437f65b4470b8042a37ccd48f399b250a77b (diff) | |
Implement multiple code changes for optimization and refactoring
Diffstat (limited to 'app')
| -rw-r--r-- | app/cmd/main.go | 132 | ||||
| -rwxr-xr-x | app/discord-bot | bin | 0 -> 425120 bytes | |||
| -rw-r--r-- | app/internal/create_bot.go | 53 | 
3 files changed, 119 insertions, 66 deletions
diff --git a/app/cmd/main.go b/app/cmd/main.go index 87212ef..7d8ffa0 100644 --- a/app/cmd/main.go +++ b/app/cmd/main.go @@ -12,25 +12,30 @@ import (  	zmq "github.com/pebbe/zmq4"  ) +var botList = make(map[string]*internal.Bot) +  func init() { -	// Initialize the application +	// Initialisation de l'application  }  func main() { +	// Créer un ServeMux  	mux := http.NewServeMux() -	// Start the application -	mux.HandleFunc("GET /", func(w http.ResponseWriter, r *http.Request) { + +	// Route principale +	mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {  		w.Write([]byte("Hello, World!"))  	}) -	botToken := "XXXXXXXXXXXX" // Replace with your bot token +	// Contexte ZeroMQ  	ctx, err := zmq.NewContext()  	if err != nil {  		log.Fatalf("[SERVER] Failed to create context: %v", err)  	}  	defer ctx.Term() +	// Socket dealer ZeroMQ  	dealer, err := ctx.NewSocket(zmq.REP)  	if err != nil {  		log.Fatalf("[SERVER] Failed to create dealer: %v", err) @@ -42,58 +47,97 @@ func main() {  		log.Fatalf("[SERVER] Failed to bind dealer: %v", err)  	} -	bot := &internal.Bot{ -		BotToken: botToken, -	} +	// Route POST /create/{bot_token} +	mux.HandleFunc("POST /create/{bot_token}", func(w http.ResponseWriter, r *http.Request) { +		// Extraire le token du bot de l'URL +		botToken := r.URL.Query().Get("bot_token") -	bot, err = internal.Start(bot, dealer) -	if err != nil { -		log.Fatalf("[SERVER] Error starting bot: %v", err) -	} -	// Handle the bot connection -	data, err := json.Marshal(map[string]interface{}{ -		"command": "update", -		"data": map[string]interface{}{ -			"ping": map[string]string{ -				"response": "pong ((userName))", -			}, -		}, +		bot := &internal.Bot{ +			BotToken: botToken, +		} +		bot, err := internal.Start(bot, dealer) +		if err != nil { +			log.Printf("[SERVER] Error starting bot: %v", err) +			http.Error(w, "Error starting bot", http.StatusInternalServerError) +			return +		} +		botList[botToken] = bot +		log.Printf("[SERVER] Bot started successfully") +		w.WriteHeader(http.StatusOK) +		w.Write([]byte("Bot started successfully"))  	}) -	if err != nil { -		log.Fatalf("[SERVER] Error marshaling JSON: %v", err) -	} -	go bot.SendMessage(string(data)) - -	dataX, err := json.Marshal(map[string]interface{}{ -		"command": "update", -		"data": map[string]interface{}{ -			"ping": map[string]string{ -				"response": "pong ((userName)) avec une modif !", -			}, -		}, + +	// Route POST /stop/{bot_token} +	mux.HandleFunc("POST /stop/{bot_token}", func(w http.ResponseWriter, r *http.Request) { +		// Extraire le token du bot de l'URL +		botToken := r.URL.Query().Get("bot_token") + +		bot, ok := botList[botToken] +		if !ok { +			http.Error(w, "Bot not found", http.StatusNotFound) +			return +		} +		if err := bot.Stop(); err != nil { +			log.Printf("[SERVER] Error stopping bot: %v", err) +			http.Error(w, "Error stopping bot", http.StatusInternalServerError) +			return +		} +		delete(botList, botToken) +		log.Printf("[SERVER] Bot stopped successfully") +		w.WriteHeader(http.StatusOK) +		w.Write([]byte("Bot stopped successfully"))  	}) -	if err != nil { -		log.Fatalf("[SERVER] Error marshaling JSON: %v", err) -	} -	go bot.SendMessage(string(dataX)) -	// Handle if signal is received +	// Route POST /update/{bot_token} +	mux.HandleFunc("POST /update/{bot_token}", func(w http.ResponseWriter, r *http.Request) { +		// Extraire le token du bot de l'URL +		botToken := r.URL.Query().Get("bot_token") +		bot, ok := botList[botToken] +		if !ok { +			http.Error(w, "Bot not found", http.StatusNotFound) +			return +		} +		body := make(map[string]interface{}) +		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 +		} +		data, err := json.Marshal(body) +		if err != nil { +			log.Printf("[SERVER] Error marshaling JSON: %v", err) +			http.Error(w, "Error marshaling JSON", http.StatusInternalServerError) +			return +		} +		if err := bot.SendMessage(string(data)); err != nil { +			log.Printf("[SERVER] Error sending message: %v", err) +			http.Error(w, "Error sending message", http.StatusInternalServerError) +			return +		} +		log.Printf("[SERVER] Bot updated successfully") +		w.WriteHeader(http.StatusOK) +		w.Write([]byte("Bot updated successfully")) +	}) + +	// Gestion des signaux pour l'arrêt propre  	signals := make(chan os.Signal, 1)  	signal.Notify(signals, os.Interrupt)  	signal.Notify(signals, syscall.SIGTERM)  	go func() {  		sig := <-signals  		log.Printf("Received signal: %s", sig) -		// let's kill the bot -		if bot.Cmd != nil { -			if err := bot.Cmd.Process.Kill(); err != nil { -				log.Printf("[SERVER] Error killing bot process: %v", err) -			} else { -				log.Printf("[SERVER] Bot process killed successfully") +		// Arrêter tous les bots en cours +		for _, bot := range botList { +			if err := bot.Stop(); err != nil { +				log.Printf("[SERVER] Error stopping bot: %v", err)  			} +			delete(botList, bot.BotToken)  		} -		// let's remove the socket +		// Quitter l'application  		os.Exit(0)  	}() -	panic(http.ListenAndServe(":2030", mux)) + +	// Démarrer le serveur HTTP +	log.Printf("[SERVER] Starting server on :2030") +	log.Fatal(http.ListenAndServe(":2030", mux))  } diff --git a/app/discord-bot b/app/discord-bot Binary files differnew file mode 100755 index 0000000..61a01e1 --- /dev/null +++ b/app/discord-bot diff --git a/app/internal/create_bot.go b/app/internal/create_bot.go index 4bbe5ae..0f47818 100644 --- a/app/internal/create_bot.go +++ b/app/internal/create_bot.go @@ -16,12 +16,13 @@ type Bot struct {  	processID int  	dealer    *zmq.Socket // Stocker le PGID (Process Group ID)  	read      bool +	readyChan chan bool // Canal pour indiquer que le bot est prêt  }  func Start(b *Bot, dealer *zmq.Socket) (*Bot, error) {  	// Configuration du bot -	cmd := exec.Command("../bot/build/discord-bot", b.BotToken) +	cmd := exec.Command("./discord-bot", b.BotToken)  	cmd.SysProcAttr = &syscall.SysProcAttr{  		Setpgid: true, // Permet de kill le processus enfant si nécessaire  	} @@ -36,18 +37,27 @@ func Start(b *Bot, dealer *zmq.Socket) (*Bot, error) {  	b.Cmd = cmd  	b.processID = cmd.Process.Pid  	b.dealer = dealer -	// Here we will receive messages from the bot in a separate goroutine -	for { -		msg, err := dealer.Recv(0) -		if err != nil { -			return nil, fmt.Errorf("[SERVER] failed to receive message: %w", err) -		} -		if msg == "ready" { -			log.Printf("[SERVER] Bot is ready") -			b.read = true -			break +	b.readyChan = make(chan bool) + +	// Goroutine pour écouter les messages du bot +	go func() { +		// Boucle de réception des messages du bot via ZeroMQ +		for { +			msg, err := dealer.Recv(0) +			if err != nil { +				log.Printf("[SERVER] Failed to receive message from bot %s: %v", b.BotToken, err) +				continue // Continue à recevoir les messages même si une erreur se produit +			} + +			if msg == "ready" { +				log.Printf("[SERVER] Bot %s is ready", b.BotToken) +				b.read = true +				b.readyChan <- true // Indiquer que le bot est prêt +				break +			}  		} -	} +	}() +  	return b, nil  } @@ -56,6 +66,7 @@ func (b *Bot) Stop() error {  		if err := syscall.Kill(-b.processID, syscall.SIGTERM); err != nil {  			return fmt.Errorf("[SERVER] failed to stop bot: %w", err)  		} +		log.Printf("[SERVER] Bot %s stopped successfully", b.BotToken)  	}  	return nil  } @@ -64,22 +75,20 @@ func (b *Bot) SendMessage(message string) error {  	if b.dealer == nil {  		return fmt.Errorf("[SERVER] sender socket is not initialized")  	} + +	// Attendre que le bot soit prêt si ce n'est pas déjà fait  	if !b.read { -		// Let's read the message before sending -		msg, err := b.dealer.Recv(0) -		if err != nil { -			return fmt.Errorf("[SERVER] failed to receive message: %w", err) -		} -		log.Printf("[SERVER] received message: %s", msg) -		b.read = true // Fix ici ! +		log.Printf("[SERVER] Waiting for bot %s to be ready...", b.BotToken) +		<-b.readyChan // Attendre que le bot soit prêt  	} +	// Envoi du message  	_, err := b.dealer.Send(message, 0)  	if err != nil { -		return fmt.Errorf("[SERVER] failed to send message: %w", err) +		return fmt.Errorf("[SERVER] failed to send message to bot %s: %w", b.BotToken, err)  	} -	log.Printf("[SERVER] sent message: %s", message) +	log.Printf("[SERVER] Sent message to bot %s: %s", b.BotToken, message) -	b.read = false +	b.read = false // Réinitialiser l'état de lecture après l'envoi  	return nil  }  | 
