package services import ( "bytes" "encoding/json" "fmt" "io" "log" "net/http" "os" "time" ) var LBTelegram *LBTelegramService type LBTelegramService struct { gatewayURL string Bot1Username string Bot2Username string client *http.Client } func NewLBTelegramService() *LBTelegramService { url := os.Getenv("LBTELEGRAM_URL") if url == "" { url = "http://lbtelegram:8081" } svc := &LBTelegramService{ gatewayURL: url, Bot1Username: os.Getenv("LBTELEGRAM_BOT1_USERNAME"), Bot2Username: os.Getenv("LBTELEGRAM_BOT2_USERNAME"), client: &http.Client{Timeout: 10 * time.Second}, } LBTelegram = svc return svc } func (s *LBTelegramService) IsConfigured() bool { return os.Getenv("LBTELEGRAM_URL") != "" } // EnrollUser enrôle un utilisateur auprès de LBTelegram après liaison du compte. // LBTelegram envoie lui-même le message de confirmation (chaîne Bot1→Bot2→Bot3). func (s *LBTelegramService) EnrollUser(chatID int64, username, role string) error { payload := map[string]interface{}{ "user_id": chatID, "username": username, "role": role, "chat_id": chatID, } body, _ := json.Marshal(payload) resp, err := s.client.Post(s.gatewayURL+"/enrollment/begin", "application/json", bytes.NewReader(body)) if err != nil { return fmt.Errorf("enrollment: %w", err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { b, _ := io.ReadAll(resp.Body) return fmt.Errorf("enrollment HTTP %d: %s", resp.StatusCode, string(b)) } log.Printf("✅ [LB] Enrollment OK pour %s (%s)", username, role) return nil } // SendNotification envoie un message via la gateway LBTelegram. // Le bot est choisi automatiquement selon la stratégie configurée (failover/roundrobin/leastconn). func (s *LBTelegramService) SendNotification(userID int64, message string) error { payload := map[string]interface{}{ "user_id": userID, "message": message, } body, _ := json.Marshal(payload) resp, err := s.client.Post(s.gatewayURL+"/notify", "application/json", bytes.NewReader(body)) if err != nil { return fmt.Errorf("notify: %w", err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { b, _ := io.ReadAll(resp.Body) return fmt.Errorf("notify HTTP %d: %s", resp.StatusCode, string(b)) } return nil }