293 lines
8.4 KiB
Go
293 lines
8.4 KiB
Go
package handlers
|
|
|
|
import (
|
|
"gestion/db"
|
|
"gestion/models"
|
|
"gestion/services"
|
|
"log"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
func TelegramWebhook(c *gin.Context) {
|
|
// Vérification du secret webhook
|
|
secret := c.GetHeader("X-Telegram-Bot-Api-Secret-Token")
|
|
if services.TelegramBot == nil || !services.TelegramBot.ValidateWebhookSecret(secret) {
|
|
c.Status(http.StatusUnauthorized)
|
|
return
|
|
}
|
|
|
|
var update models.TgUpdate
|
|
if err := c.ShouldBindJSON(&update); err != nil {
|
|
c.Status(http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
if update.Message == nil {
|
|
c.Status(http.StatusOK)
|
|
return
|
|
}
|
|
|
|
text := strings.TrimSpace(update.Message.Text)
|
|
chatID := update.Message.Chat.ID
|
|
|
|
// Commande /start <token> — liaison de compte
|
|
if token, ok := strings.CutPrefix(text, "/start "); ok {
|
|
token = strings.TrimSpace(token)
|
|
handleLinkAccount(c, token, chatID)
|
|
return
|
|
}
|
|
|
|
// Commande /start sans token — message d'accueil
|
|
if text == "/start" {
|
|
if services.TelegramBot != nil {
|
|
services.TelegramBot.SendMessage(chatID,
|
|
"👋 <b>Bienvenue !</b>\n\nPour lier votre compte, générez un token depuis l'application et envoyez <code>/start <token></code>.")
|
|
}
|
|
}
|
|
|
|
c.Status(http.StatusOK)
|
|
}
|
|
|
|
func handleLinkAccount(c *gin.Context, token string, chatID int64) {
|
|
if token == "" {
|
|
if services.TelegramBot != nil {
|
|
services.TelegramBot.SendMessage(chatID, "❌ Token manquant. Générez un nouveau token depuis l'application.")
|
|
}
|
|
c.Status(http.StatusOK)
|
|
return
|
|
}
|
|
|
|
database := c.MustGet("database").(*db.Database)
|
|
|
|
username, role, err := db.ValidateAndConsumeLinkToken(token)
|
|
if err != nil {
|
|
log.Printf("⚠️ [TELEGRAM_LINK] Token invalide: %v", err)
|
|
if services.TelegramBot != nil {
|
|
services.TelegramBot.SendMessage(chatID, "❌ Token invalide ou expiré. Générez un nouveau token depuis l'application.")
|
|
}
|
|
c.Status(http.StatusOK)
|
|
return
|
|
}
|
|
|
|
// Enregistrer le chat_id selon le rôle
|
|
var saveErr error
|
|
switch role {
|
|
case "client":
|
|
saveErr = database.SaveClientTelegramChatID(username, chatID)
|
|
default:
|
|
saveErr = database.SaveUserTelegramChatID(username, chatID)
|
|
}
|
|
|
|
if saveErr != nil {
|
|
log.Printf("❌ [TELEGRAM_LINK] Erreur sauvegarde chat_id pour %s (%s): %v", username, role, saveErr)
|
|
if services.TelegramBot != nil {
|
|
services.TelegramBot.SendMessage(chatID, "❌ Une erreur est survenue. Réessayez.")
|
|
}
|
|
c.Status(http.StatusOK)
|
|
return
|
|
}
|
|
|
|
log.Printf("✅ [TELEGRAM_LINK] Compte %s (%s) lié au chat_id %d", username, role, chatID)
|
|
if services.TelegramBot != nil {
|
|
services.TelegramBot.SendMessage(chatID,
|
|
"✅ <b>Compte lié avec succès !</b>\n\nVous recevrez désormais vos notifications ici.")
|
|
}
|
|
|
|
c.Status(http.StatusOK)
|
|
}
|
|
|
|
func GenerateClientLinkToken(c *gin.Context) {
|
|
username := c.GetString("username")
|
|
if username == "" {
|
|
c.JSON(http.StatusUnauthorized, gin.H{"error": "Non authentifié"})
|
|
return
|
|
}
|
|
|
|
if services.TelegramBot == nil || !services.TelegramBot.IsConfigured() {
|
|
c.JSON(http.StatusServiceUnavailable, gin.H{"error": "Service Telegram non disponible"})
|
|
return
|
|
}
|
|
|
|
token, err := db.GenerateLinkToken(username, "client")
|
|
if err != nil {
|
|
log.Printf("❌ [TELEGRAM] Erreur génération token pour %s: %v", username, err)
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Erreur génération token"})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"token": token,
|
|
"link_url": "https://t.me/" + services.TelegramBot.BotUsername + "?start=" + token,
|
|
"message": "/start " + token,
|
|
"expires_in": 600,
|
|
})
|
|
}
|
|
|
|
func GenerateLivreurLinkToken(c *gin.Context) {
|
|
username := c.GetString("username")
|
|
if username == "" {
|
|
c.JSON(http.StatusUnauthorized, gin.H{"error": "Non authentifié"})
|
|
return
|
|
}
|
|
|
|
if services.TelegramBot == nil || !services.TelegramBot.IsConfigured() {
|
|
c.JSON(http.StatusServiceUnavailable, gin.H{"error": "Service Telegram non disponible"})
|
|
return
|
|
}
|
|
|
|
token, err := db.GenerateLinkToken(username, "livreur")
|
|
if err != nil {
|
|
log.Printf("❌ [TELEGRAM] Erreur génération token pour livreur %s: %v", username, err)
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Erreur génération token"})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"token": token,
|
|
"link_url": "https://t.me/" + services.TelegramBot.BotUsername + "?start=" + token,
|
|
"message": "/start " + token,
|
|
"expires_in": 600,
|
|
})
|
|
}
|
|
|
|
func GenerateAdminLinkToken(c *gin.Context) {
|
|
username := c.GetString("username")
|
|
if username == "" {
|
|
c.JSON(http.StatusUnauthorized, gin.H{"error": "Non authentifié"})
|
|
return
|
|
}
|
|
|
|
if services.TelegramBot == nil || !services.TelegramBot.IsConfigured() {
|
|
c.JSON(http.StatusServiceUnavailable, gin.H{"error": "Service Telegram non disponible"})
|
|
return
|
|
}
|
|
|
|
// Récupérer le rôle réel depuis la DB
|
|
database := c.MustGet("database").(*db.Database)
|
|
user, err := database.GetUserByUsername(username)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Utilisateur introuvable"})
|
|
return
|
|
}
|
|
|
|
token, err := db.GenerateLinkToken(username, user.Role)
|
|
if err != nil {
|
|
log.Printf("❌ [TELEGRAM] Erreur génération token pour admin %s: %v", username, err)
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Erreur génération token"})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"token": token,
|
|
"link_url": "https://t.me/" + services.TelegramBot.BotUsername + "?start=" + token,
|
|
"message": "/start " + token,
|
|
"expires_in": 600,
|
|
})
|
|
}
|
|
|
|
// GET /api/v1/telegram/status
|
|
func GetClientTelegramStatus(c *gin.Context) {
|
|
username := c.GetString("username")
|
|
if username == "" {
|
|
c.JSON(http.StatusUnauthorized, gin.H{"error": "Non authentifié"})
|
|
return
|
|
}
|
|
|
|
database := c.MustGet("database").(*db.Database)
|
|
_, linked, err := database.GetClientTelegramChatID(username)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Erreur vérification"})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"linked": linked,
|
|
"enabled": services.TelegramBot != nil && services.TelegramBot.IsConfigured(),
|
|
})
|
|
}
|
|
|
|
// GET /api/v1/livreur/telegram/status
|
|
func GetLivreurTelegramStatus(c *gin.Context) {
|
|
username := c.GetString("username")
|
|
if username == "" {
|
|
c.JSON(http.StatusUnauthorized, gin.H{"error": "Non authentifié"})
|
|
return
|
|
}
|
|
|
|
database := c.MustGet("database").(*db.Database)
|
|
_, linked, err := database.GetUserTelegramChatID(username)
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Erreur vérification"})
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"linked": linked,
|
|
"enabled": services.TelegramBot != nil && services.TelegramBot.IsConfigured(),
|
|
})
|
|
}
|
|
|
|
// ============================================
|
|
// DÉLIAISON TELEGRAM
|
|
// ============================================
|
|
|
|
// DELETE /api/v1/telegram/unlink
|
|
func UnlinkClientTelegram(c *gin.Context) {
|
|
username := c.GetString("username")
|
|
if username == "" {
|
|
c.JSON(http.StatusUnauthorized, gin.H{"error": "Non authentifié"})
|
|
return
|
|
}
|
|
|
|
database := c.MustGet("database").(*db.Database)
|
|
if err := database.DeleteClientTelegramChatID(username); err != nil {
|
|
log.Printf("❌ [TELEGRAM_UNLINK] Erreur pour %s: %v", username, err)
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Erreur déliaison"})
|
|
return
|
|
}
|
|
|
|
log.Printf("✅ [TELEGRAM_UNLINK] Compte client %s délié", username)
|
|
c.JSON(http.StatusOK, gin.H{"success": true})
|
|
}
|
|
|
|
// DELETE /api/v1/livreur/telegram/unlink
|
|
func UnlinkLivreurTelegram(c *gin.Context) {
|
|
username := c.GetString("username")
|
|
if username == "" {
|
|
c.JSON(http.StatusUnauthorized, gin.H{"error": "Non authentifié"})
|
|
return
|
|
}
|
|
|
|
database := c.MustGet("database").(*db.Database)
|
|
if err := database.DeleteUserTelegramChatID(username); err != nil {
|
|
log.Printf("❌ [TELEGRAM_UNLINK] Erreur pour %s: %v", username, err)
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Erreur déliaison"})
|
|
return
|
|
}
|
|
|
|
log.Printf("✅ [TELEGRAM_UNLINK] Compte livreur %s délié", username)
|
|
c.JSON(http.StatusOK, gin.H{"success": true})
|
|
}
|
|
|
|
// DELETE /api/v2/admin/protected/telegram/unlink
|
|
func UnlinkAdminTelegram(c *gin.Context) {
|
|
username := c.GetString("username")
|
|
if username == "" {
|
|
c.JSON(http.StatusUnauthorized, gin.H{"error": "Non authentifié"})
|
|
return
|
|
}
|
|
|
|
database := c.MustGet("database").(*db.Database)
|
|
if err := database.DeleteUserTelegramChatID(username); err != nil {
|
|
log.Printf("❌ [TELEGRAM_UNLINK] Erreur pour %s: %v", username, err)
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Erreur déliaison"})
|
|
return
|
|
}
|
|
|
|
log.Printf("✅ [TELEGRAM_UNLINK] Compte admin %s délié", username)
|
|
c.JSON(http.StatusOK, gin.H{"success": true})
|
|
}
|