summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorsoler_j <soler_j@etna-alternance.net>2025-04-29 10:50:45 +0200
committersoler_j <soler_j@etna-alternance.net>2025-04-29 10:50:45 +0200
commit3d143c271394a942dff5d979ffc8d2c55f1644dc (patch)
tree7191a49baacebe7a8bbb46b82c8d8f1f96bf5f0e /app
parent22dc3abd0c866e4ee292a4648c3dac5cda2583cb (diff)
Refactor Dockerfile and bot code: remove ZeroMQ dependencies, enhance bot initialization with HTTP webhook server, and improve error handling for bot startup.
Diffstat (limited to 'app')
-rw-r--r--app/cmd/main.go32
-rw-r--r--app/go.mod5
-rw-r--r--app/internal/create_bot.go74
3 files changed, 47 insertions, 64 deletions
diff --git a/app/cmd/main.go b/app/cmd/main.go
index 49e645f..2232c8e 100644
--- a/app/cmd/main.go
+++ b/app/cmd/main.go
@@ -40,7 +40,37 @@ func main() {
ProcessID: fmt.Sprint(len(botList) + 5555), // or any unique identifier
}
- bot, err := internal.Start(bot)
+ // Let's check if this discord bot exists
+ if _, ok := botList[botToken]; ok {
+ log.Printf("[SERVER] Bot already running: %s", botToken)
+ http.Error(w, "Bot already running", http.StatusConflict)
+ return
+ }
+
+ // let's check if it exist on Discord
+ httpClient := &http.Client{}
+ req, err := http.NewRequest("GET", "https://discord.com/api/v10/users/@me", nil)
+ if err != nil {
+ log.Printf("[SERVER] Error creating request: %v", err)
+ http.Error(w, "Error creating request", http.StatusInternalServerError)
+ return
+ }
+ req.Header.Set("Authorization", "Bot "+botToken)
+ resp, err := httpClient.Do(req)
+ if err != nil {
+ log.Printf("[SERVER] Error sending request: %v", err)
+ http.Error(w, "Error sending request", http.StatusInternalServerError)
+ return
+ }
+ defer resp.Body.Close()
+ if resp.StatusCode != http.StatusOK {
+ log.Printf("[SERVER] Bot not found: %s", botToken)
+ http.Error(w, "Bot not found", http.StatusNotFound)
+ return
+ }
+ // let's check if the bot is already running
+
+ bot, err = internal.Start(bot)
if err != nil {
log.Printf("[SERVER] Error starting bot: %v", err)
http.Error(w, "Error starting bot", http.StatusInternalServerError)
diff --git a/app/go.mod b/app/go.mod
index 86e0320..0fdbadd 100644
--- a/app/go.mod
+++ b/app/go.mod
@@ -2,7 +2,4 @@ module github.com/ketsuna-org/bot-creator-api
go 1.23.3
-require (
- github.com/arangodb/go-driver/v2 v2.1.3 // indirect
- github.com/pebbe/zmq4 v1.3.1 // indirect
-)
+require github.com/arangodb/go-driver/v2 v2.1.3 // indirect
diff --git a/app/internal/create_bot.go b/app/internal/create_bot.go
index 667ac0a..ce70cdd 100644
--- a/app/internal/create_bot.go
+++ b/app/internal/create_bot.go
@@ -3,45 +3,22 @@ package internal
import (
"fmt"
"log"
+ "net/http"
"os"
"os/exec"
+ "strings"
"syscall"
-
- zmq "github.com/pebbe/zmq4"
)
type Bot struct {
BotToken string `json:"bot_token"`
Cmd *exec.Cmd // Ajouter une référence à la commande
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
+ client *http.Client
}
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, b.ProcessID) // Passer le port unique
cmd.SysProcAttr = &syscall.SysProcAttr{
@@ -56,20 +33,11 @@ func Start(b *Bot) (*Bot, error) {
return nil, fmt.Errorf("failed to start bot: %w", err)
}
b.Cmd = cmd
- 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
- }
- }
+ client := http.Client{}
+ // Send data to the bot
+ b.client = &client
+ log.Printf("[SERVER] Bot %s started successfully with PID %d", b.BotToken, cmd.Process.Pid)
return b, nil
}
@@ -84,22 +52,6 @@ func (b *Bot) Stop() error {
}
func (b *Bot) SendMessage(message string) error {
- if b.dealer == nil {
- return fmt.Errorf("[SERVER] sender socket is not initialized")
- }
-
- // 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)
- // 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)
@@ -111,12 +63,16 @@ func (b *Bot) SendMessage(message string) error {
}
// Send the message
- _, err := b.dealer.Send(message, 0)
+ resp, err := b.client.Post("http://localhost:"+b.ProcessID, "application/json", strings.NewReader(message))
if err != nil {
- return fmt.Errorf("[SERVER] failed to send message to bot %s: %w", b.BotToken, err)
+ return fmt.Errorf("[SERVER] failed to send message: %w", err)
+ }
+ defer resp.Body.Close()
+ if resp.StatusCode != http.StatusOK {
+ return fmt.Errorf("[SERVER] failed to send message: %s", resp.Status)
}
- log.Printf("[SERVER] Sent message to bot %s: %s", b.BotToken, message)
+ // Log the message sent
+ log.Printf("[SERVER] Message sent to bot %s: %s", b.BotToken, message)
- b.read = false // Reset read state after sending the message
return nil
}