package handler import ( "crypto/subtle" "log" "net/http" "homework-manager/internal/service" "github.com/gin-gonic/gin" ) // TelegramHandler handles incoming Telegram webhook requests. type TelegramHandler struct { telegramService *service.TelegramService webhookSecret string } // NewTelegramHandler creates a TelegramHandler. func NewTelegramHandler(telegramService *service.TelegramService, webhookSecret string) *TelegramHandler { return &TelegramHandler{ telegramService: telegramService, webhookSecret: webhookSecret, } } // Webhook is the endpoint registered as the Telegram bot webhook. // POST /api/telegram/webhook func (h *TelegramHandler) Webhook(c *gin.Context) { if h.webhookSecret == "" { c.Status(http.StatusServiceUnavailable) return } secret := c.GetHeader("X-Telegram-Bot-Api-Secret-Token") if subtle.ConstantTimeCompare([]byte(secret), []byte(h.webhookSecret)) != 1 { c.Status(http.StatusUnauthorized) return } var update service.TelegramUpdate if err := c.ShouldBindJSON(&update); err != nil { c.Status(http.StatusBadRequest) return } // Process asynchronously so Telegram gets a 200 within its timeout window. go func() { defer func() { if r := recover(); r != nil { log.Printf("telegram HandleUpdate panic: %v", r) } }() h.telegramService.HandleUpdate(update) }() c.Status(http.StatusOK) }