mirror of
https://github.com/truewhile/MeBox.git
synced 2026-09-29 03:26:37 +08:00
5baf9515ea
## 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 表格溢出截断
100 lines
3.0 KiB
Go
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"})
|
|
}
|
|
}
|