summaryrefslogtreecommitdiff
path: root/app/internal/create_bot.go
diff options
context:
space:
mode:
Diffstat (limited to 'app/internal/create_bot.go')
-rw-r--r--app/internal/create_bot.go90
1 files changed, 59 insertions, 31 deletions
diff --git a/app/internal/create_bot.go b/app/internal/create_bot.go
index 0f47818..667ac0a 100644
--- a/app/internal/create_bot.go
+++ b/app/internal/create_bot.go
@@ -13,18 +13,39 @@ import (
type Bot struct {
BotToken string `json:"bot_token"`
Cmd *exec.Cmd // Ajouter une référence à la commande
- processID int
+ ProcessID string
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) {
+func Start(b *Bot) (*Bot, error) {
+ if b.readyChan == nil {
+ b.readyChan = make(chan bool)
+ }
+
+ // Create a new ZeroMQ socket specifically for this bot
+ ctx, err := zmq.NewContext()
+ if err != nil {
+ return nil, fmt.Errorf("[SERVER] failed to create context: %w", err)
+ }
+
+ // Each bot gets its own dealer socket
+ dealer, err := ctx.NewSocket(zmq.REP)
+ if err != nil {
+ return nil, fmt.Errorf("[SERVER] failed to create dealer: %w", err)
+ }
+
+ // Binding the socket to a specific address (may need to adjust the address based on your needs)
+ err = dealer.Bind(fmt.Sprintf("tcp://localhost:%s", b.ProcessID))
+ if err != nil {
+ return nil, fmt.Errorf("[SERVER] failed to bind dealer: %w", err)
+ }
// Configuration du bot
- cmd := exec.Command("./discord-bot", b.BotToken)
+ cmd := exec.Command("./discord-bot", b.BotToken, b.ProcessID) // Passer le port unique
cmd.SysProcAttr = &syscall.SysProcAttr{
- Setpgid: true, // Permet de kill le processus enfant si nécessaire
+ Setpgid: true, // Permet de tuer le processus enfant si nécessaire
}
// Redirection des sorties pour le débogage
@@ -35,35 +56,26 @@ func Start(b *Bot, dealer *zmq.Socket) (*Bot, error) {
return nil, fmt.Errorf("failed to start bot: %w", err)
}
b.Cmd = cmd
- b.processID = cmd.Process.Pid
b.dealer = dealer
- 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
- }
- }
- }()
+ // 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
+ }
+ }
return b, nil
}
func (b *Bot) Stop() error {
- if b.Cmd != nil && b.processID != 0 {
- if err := syscall.Kill(-b.processID, syscall.SIGTERM); err != nil {
+ if b.Cmd != nil && b.Cmd.Process.Pid != 0 {
+ if err := syscall.Kill(-b.Cmd.Process.Pid, syscall.SIGTERM); err != nil {
return fmt.Errorf("[SERVER] failed to stop bot: %w", err)
}
log.Printf("[SERVER] Bot %s stopped successfully", b.BotToken)
@@ -76,19 +88,35 @@ func (b *Bot) SendMessage(message string) error {
return fmt.Errorf("[SERVER] sender socket is not initialized")
}
- // Attendre que le bot soit prêt si ce n'est pas déjà fait
+ // Wait for the bot to be ready if it's not already
if !b.read {
log.Printf("[SERVER] Waiting for bot %s to be ready...", b.BotToken)
- <-b.readyChan // Attendre que le bot soit prêt
+ // this mean we should read the recv channel
+ msg, err := b.dealer.Recv(0)
+ if err != nil {
+ return fmt.Errorf("[SERVER] failed to receive message: %w", err)
+ }
+ log.Printf("[SERVER] Received message from bot %s: %s", b.BotToken, msg)
+ b.read = true
+ }
+
+ // Check if the bot process is still running
+ if err := b.Cmd.Process.Signal(syscall.Signal(0)); err != nil {
+ return fmt.Errorf("[SERVER] bot process is not running: %w", err)
+ }
+
+ // Check if the message is empty
+ if message == "" {
+ return fmt.Errorf("[SERVER] message is empty")
}
- // Envoi du message
+ // Send the message
_, err := b.dealer.Send(message, 0)
if err != nil {
return fmt.Errorf("[SERVER] failed to send message to bot %s: %w", b.BotToken, err)
}
log.Printf("[SERVER] Sent message to bot %s: %s", b.BotToken, message)
- b.read = false // Réinitialiser l'état de lecture après l'envoi
+ b.read = false // Reset read state after sending the message
return nil
}