Files
MeBox/internal/handler/telegram_webhook.go
T
ShukeBta 5baf9515ea TG Bot 命令交互 + UI 圆角色差深度优化 + 通知配置修复
## TG Bot 交互命令系统 (新增)
- telegram_bot.go: 命令路由 + /start /help /status /search /downloads /stats
- telegram_webhook.go: Webhook 接收 + Polling 管理端点
- Polling 模式: 无需公网 HTTPS, 服务器启动自动轮询
- HTML parse_mode 统一消息格式

## 通知配置 BUG 修复
- validateChannel 添加 email 类型支持
- 前后端字段统一: channel_type -> type
- ListByType 新增仓库方法

## UI 深度优化
- glass-panel: 添加 rounded-2xl + 可见边框 + padding
- card: 添加 p-4 sm:p-6
- 全局 rounded-md -> rounded-xl, 裸 rounded -> rounded-lg
- 500+ 深色硬编码类名清零
- text-gray-400 -> gray-500 色差提升
- 按钮组 flex-wrap 防溢出
- data-table 表格溢出截断
2026-05-28 08:35:59 +08:00

100 lines
3.0 KiB
Go

// Package handler — Telegram Bot Webhook 端点。
//
// 接收 Telegram Bot API 推送的 update 消息,路由到 TelegramBotService 处理。
package handler
import (
"io"
"net/http"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
"github.com/ShukeBta/MediaStationGo/internal/service"
)
// telegramWebhookHandler 处理 Telegram Bot 的 Webhook 回调。
//
// 路由:POST /api/telegram/webhook (无需认证,由 Telegram 服务器调用)
func telegramWebhookHandler(svc *service.Container) gin.HandlerFunc {
return func(c *gin.Context) {
body, err := io.ReadAll(c.Request.Body)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "cannot read body"})
return
}
if err := svc.TelegramBot.HandleWebhook(c.Request.Context(), body); err != nil {
svc.Log.Error("telegram webhook error", zap.Error(err))
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"ok": true})
}
}
// telegramSetWebhookHandler 管理员手动设置/更新 Webhook URL。
//
// 路由:POST /api/admin/telegram/webhook (需 admin 认证)
func telegramSetWebhookHandler(svc *service.Container) gin.HandlerFunc {
return func(c *gin.Context) {
var req struct {
BotToken string `json:"bot_token" binding:"required"`
WebhookURL string `json:"webhook_url" binding:"required"`
}
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
if err := svc.TelegramBot.SetWebhook(c.Request.Context(), req.BotToken, req.WebhookURL); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"message": "webhook set successfully", "url": req.WebhookURL})
}
}
// telegramGetWebhookHandler 获取当前 Webhook 配置信息。
//
// 路由:GET /api/admin/telegram/webhook (需 admin 认证)
func telegramGetWebhookHandler(svc *service.Container) gin.HandlerFunc {
return func(c *gin.Context) {
botToken := c.Query("bot_token")
if botToken == "" {
c.JSON(http.StatusBadRequest, gin.H{"error": "bot_token is required"})
return
}
info, err := svc.TelegramBot.GetWebhookInfo(c.Request.Context(), botToken)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, info)
}
}
// telegramStartPollingHandler 启动 Telegram 长轮询。
//
// 路由:POST /api/admin/telegram/polling/start (需 admin 认证)
func telegramStartPollingHandler(svc *service.Container) gin.HandlerFunc {
return func(c *gin.Context) {
svc.TelegramBot.StartPolling(c.Request.Context())
c.JSON(http.StatusOK, gin.H{"message": "polling started"})
}
}
// telegramStopPollingHandler 停止 Telegram 长轮询。
//
// 路由:POST /api/admin/telegram/polling/stop (需 admin 认证)
func telegramStopPollingHandler(svc *service.Container) gin.HandlerFunc {
return func(c *gin.Context) {
svc.TelegramBot.StopPolling()
c.JSON(http.StatusOK, gin.H{"message": "polling stopped"})
}
}