update: 添加tg调试代码

This commit is contained in:
ctwj
2025-11-21 00:03:07 +08:00
parent 447512d809
commit fc4cf8ecfb
6 changed files with 206 additions and 13 deletions

View File

@@ -511,6 +511,27 @@ func (h *TelegramHandler) GetTelegramLogStats(c *gin.Context) {
})
}
// ManualPushToChannel 手动推送到频道
func (h *TelegramHandler) ManualPushToChannel(c *gin.Context) {
idStr := c.Param("id")
channelID, err := strconv.ParseUint(idStr, 10, 32)
if err != nil {
ErrorResponse(c, "无效的频道ID", http.StatusBadRequest)
return
}
err = h.telegramBotService.ManualPushToChannel(uint(channelID))
if err != nil {
ErrorResponse(c, "手动推送失败: "+err.Error(), http.StatusInternalServerError)
return
}
SuccessResponse(c, map[string]interface{}{
"success": true,
"message": "手动推送请求已提交",
})
}
// ClearTelegramLogs 清理旧的Telegram日志
func (h *TelegramHandler) ClearTelegramLogs(c *gin.Context) {
daysStr := c.DefaultQuery("days", "30")

View File

@@ -435,6 +435,7 @@ func main() {
api.GET("/telegram/logs/stats", middleware.AuthMiddleware(), middleware.AdminMiddleware(), telegramHandler.GetTelegramLogStats)
api.POST("/telegram/logs/clear", middleware.AuthMiddleware(), middleware.AdminMiddleware(), telegramHandler.ClearTelegramLogs)
api.POST("/telegram/webhook", telegramHandler.HandleWebhook)
api.POST("/telegram/manual-push/:id", middleware.AuthMiddleware(), middleware.AdminMiddleware(), telegramHandler.ManualPushToChannel)
// 微信公众号相关路由
wechatHandler := handlers.NewWechatHandler(

View File

@@ -39,6 +39,7 @@ type TelegramBotService interface {
IsChannelRegistered(chatID int64) bool
HandleWebhookUpdate(c interface{})
CleanupDuplicateChannels() error
ManualPushToChannel(channelID uint) error
}
type TelegramBotServiceImpl struct {
@@ -1072,6 +1073,10 @@ func (s *TelegramBotServiceImpl) findResourcesForChannel(channel entity.Telegram
func (s *TelegramBotServiceImpl) findLatestResources(channel entity.TelegramChannel, excludeResourceIDs []uint) []interface{} {
params := s.buildFilterParams(channel)
// 添加按创建时间倒序的排序参数,确保获取最新资源
params["order_by"] = "created_at"
params["order_dir"] = "DESC"
// 在数据库查询中排除已推送的资源
if len(excludeResourceIDs) > 0 {
params["exclude_ids"] = excludeResourceIDs
@@ -1330,15 +1335,23 @@ func (s *TelegramBotServiceImpl) SendMessage(chatID int64, text string, img stri
} else {
// 如果 img 以 http 开头则为图片URL否则为文件remote_id
if strings.HasPrefix(img, "http") {
// 发送图片URL
photoMsg := tgbotapi.NewPhoto(chatID, tgbotapi.FileURL(img))
photoMsg.Caption = text
photoMsg.ParseMode = "HTML"
_, err := s.bot.Send(photoMsg)
if err != nil {
utils.Error("[TELEGRAM:MESSAGE:ERROR] 发送图片消息失败: %v", err)
// 发送图片URL前先验证URL是否可访问并返回有效的图片格式
if s.isValidImageURL(img) {
photoMsg := tgbotapi.NewPhoto(chatID, tgbotapi.FileURL(img))
photoMsg.Caption = text
photoMsg.ParseMode = "HTML"
_, err := s.bot.Send(photoMsg)
if err != nil {
utils.Error("[TELEGRAM:MESSAGE:ERROR] 发送图片消息失败: %v", err)
// 如果URL方式失败尝试将URL作为普通文本发送
return s.sendTextMessage(chatID, text)
}
return err
} else {
utils.Warn("[TELEGRAM:MESSAGE:WARNING] 图片URL无效仅发送文本消息: %s", img)
// URL无效时只发送文本消息
return s.sendTextMessage(chatID, text)
}
return err
} else {
// imgUrl := s.GetImgUrl(img)
//todo 判断 imgUrl 是否可用
@@ -1349,12 +1362,85 @@ func (s *TelegramBotServiceImpl) SendMessage(chatID int64, text string, img stri
_, err := s.bot.Send(photoMsg)
if err != nil {
utils.Error("[TELEGRAM:MESSAGE:ERROR] 发送图片消息失败: %v", err)
// 如果文件ID方式失败尝试将URL作为普通文本发送
return s.sendTextMessage(chatID, text)
}
return err
}
}
}
// isValidImageURL 验证图片URL是否有效
func (s *TelegramBotServiceImpl) isValidImageURL(imageURL string) bool {
client := &http.Client{
Timeout: 10 * time.Second,
}
// 如果配置了代理,设置代理
if s.config.ProxyEnabled && s.config.ProxyHost != "" {
var proxyClient *http.Client
if s.config.ProxyType == "socks5" {
auth := &proxy.Auth{}
if s.config.ProxyUsername != "" {
auth.User = s.config.ProxyUsername
auth.Password = s.config.ProxyPassword
}
dialer, proxyErr := proxy.SOCKS5("tcp", fmt.Sprintf("%s:%d", s.config.ProxyHost, s.config.ProxyPort), auth, proxy.Direct)
if proxyErr != nil {
utils.Warn("[TELEGRAM:IMAGE] 代理配置错误: %v", proxyErr)
return false
}
proxyClient = &http.Client{
Transport: &http.Transport{
Dial: dialer.Dial,
},
Timeout: 10 * time.Second,
}
} else {
proxyURL := &url.URL{
Scheme: s.config.ProxyType,
Host: fmt.Sprintf("%s:%d", s.config.ProxyHost, s.config.ProxyPort),
}
if s.config.ProxyUsername != "" {
proxyURL.User = url.UserPassword(s.config.ProxyUsername, s.config.ProxyPassword)
}
proxyClient = &http.Client{
Transport: &http.Transport{
Proxy: http.ProxyURL(proxyURL),
},
Timeout: 10 * time.Second,
}
}
client = proxyClient
}
resp, err := client.Head(imageURL)
if err != nil {
utils.Warn("[TELEGRAM:IMAGE] 检查图片URL失败: %v, URL: %s", err, imageURL)
return false
}
defer resp.Body.Close()
// 检查Content-Type是否为图片格式
contentType := resp.Header.Get("Content-Type")
isImage := strings.HasPrefix(contentType, "image/")
if !isImage {
utils.Warn("[TELEGRAM:IMAGE] URL不是图片格式: %s, Content-Type: %s", imageURL, contentType)
}
return isImage
}
// sendTextMessage 仅发送文本消息的辅助方法
func (s *TelegramBotServiceImpl) sendTextMessage(chatID int64, text string) error {
msg := tgbotapi.NewMessage(chatID, text)
msg.ParseMode = "HTML"
_, err := s.bot.Send(msg)
if err != nil {
utils.Error("[TELEGRAM:MESSAGE:ERROR] 发送文本消息失败: %v", err)
}
return err
}
// DeleteMessage 删除消息
func (s *TelegramBotServiceImpl) DeleteMessage(chatID int64, messageID int) error {
if s.bot == nil {
@@ -2017,3 +2103,25 @@ func (s *TelegramBotServiceImpl) isChannelInPushTimeRange(channel entity.Telegra
return currentTime >= startTime || currentTime <= endTime
}
}
// ManualPushToChannel 手动推送内容到指定频道
func (s *TelegramBotServiceImpl) ManualPushToChannel(channelID uint) error {
// 获取指定频道信息
channel, err := s.channelRepo.FindByID(channelID)
if err != nil {
return fmt.Errorf("找不到指定的频道: %v", err)
}
utils.Info("[TELEGRAM:MANUAL_PUSH] 开始手动推送到频道: %s (ID: %d)", channel.ChatName, channel.ChatID)
// 检查频道是否启用推送
if !channel.PushEnabled {
return fmt.Errorf("频道 %s 未启用推送功能", channel.ChatName)
}
// 推送内容到频道,使用频道配置的策略
s.pushToChannel(*channel)
utils.Info("[TELEGRAM:MANUAL_PUSH] 手动推送请求已提交: %s (ID: %d)", channel.ChatName, channel.ChatID)
return nil
}

View File

@@ -279,6 +279,16 @@
<n-tag :type="channel.is_active ? 'success' : 'warning'" size="small">
{{ channel.is_active ? '活跃' : '非活跃' }}
</n-tag>
<n-button
v-if="channel.push_enabled"
size="small"
@click="manualPushToChannel(channel)"
:loading="manualPushingChannel === channel.id"
title="手动推送">
<template #icon>
<i class="fas fa-paper-plane"></i>
</template>
</n-button>
<n-button size="small" @click="editChannel(channel)">
<template #icon>
<i class="fas fa-edit"></i>
@@ -715,6 +725,8 @@ const loadingLogs = ref(false)
const logHours = ref(24)
const editingChannel = ref<any>(null)
const savingChannel = ref(false)
const testingPush = ref(false)
const manualPushingChannel = ref<number | null>(null)
// 机器人状态相关变量
const botStatus = ref<any>(null)
@@ -1469,6 +1481,55 @@ const refreshBotStatus = async () => {
}
}
// 手动推送内容到频道
const manualPushToChannel = async (channel: any) => {
if (!channel || !channel.id) {
notification.warning({
content: '频道信息不完整',
duration: 2000
})
return
}
if (!telegramBotConfig.value.bot_enabled) {
notification.warning({
content: '请先启用机器人并配置API Key',
duration: 3000
})
return
}
manualPushingChannel.value = channel.id
try {
await telegramApi.manualPushToChannel(channel.id)
notification.success({
content: `手动推送请求已提交至频道 "${channel.chat_name}"`,
duration: 3000
})
// 更新频道推送时间
const updatedChannels = telegramChannels.value.map(c => {
if (c.id === channel.id) {
c.last_push_at = new Date().toISOString()
}
return c
})
telegramChannels.value = updatedChannels
} catch (error: any) {
console.error('手动推送失败:', error)
notification.error({
content: `手动推送失败: ${error?.message || '请稍后重试'}`,
duration: 3000
})
} finally {
// 只有当当前频道ID与推送中的频道ID匹配时才清除状态
if (manualPushingChannel.value === channel.id) {
manualPushingChannel.value = null
}
}
}
// 调试机器人连接
const debugBotConnection = async () => {
try {

View File

@@ -305,6 +305,7 @@ export const useTelegramApi = () => {
const debugBotConnection = () => useApiFetch('/telegram/debug-connection').then(parseApiResponse)
const reloadBotConfig = () => useApiFetch('/telegram/reload-config', { method: 'POST' }).then(parseApiResponse)
const testBotMessage = (data: any) => useApiFetch('/telegram/test-message', { method: 'POST', body: data }).then(parseApiResponse)
const manualPushToChannel = (channelId: number) => useApiFetch(`/telegram/manual-push/${channelId}`, { method: 'POST' }).then(parseApiResponse)
const getChannels = () => useApiFetch('/telegram/channels').then(parseApiResponse)
const createChannel = (data: any) => useApiFetch('/telegram/channels', { method: 'POST', body: data }).then(parseApiResponse)
const updateChannel = (id: number, data: any) => useApiFetch(`/telegram/channels/${id}`, { method: 'PUT', body: data }).then(parseApiResponse)
@@ -320,6 +321,7 @@ export const useTelegramApi = () => {
debugBotConnection,
reloadBotConfig,
testBotMessage,
manualPushToChannel,
getChannels,
createChannel,
updateChannel,

View File

@@ -172,7 +172,7 @@ export const useSystemConfigStore = defineStore('systemConfig', {
this.error = null
try {
console.log(`[SystemConfig] 开始获取配置 (force: ${force}, useAdminApi: ${useAdminApi})`)
// console.log(`[SystemConfig] 开始获取配置 (force: ${force}, useAdminApi: ${useAdminApi})`)
// 根据上下文选择API管理员页面使用管理员API其他页面使用公开API
const apiUrl = useAdminApi ? '/system/config' : '/public/system-config'
@@ -189,14 +189,14 @@ export const useSystemConfigStore = defineStore('systemConfig', {
// 保存到缓存(仅在客户端)
this.saveToCache(data)
console.log('[SystemConfig] 配置获取并缓存成功')
console.log('[SystemConfig] 自动处理状态:', data.auto_process_ready_resources)
console.log('[SystemConfig] 自动转存状态:', data.auto_transfer_enabled)
// console.log('[SystemConfig] 配置获取并缓存成功')
// console.log('[SystemConfig] 自动处理状态:', data.auto_process_ready_resources)
// console.log('[SystemConfig] 自动转存状态:', data.auto_transfer_enabled)
} catch (error) {
this.isLoading = false
this.error = error instanceof Error ? error.message : '获取配置失败'
console.error('[SystemConfig] 获取系统配置失败:', error)
// console.error('[SystemConfig] 获取系统配置失败:', error)
// 如果网络请求失败,尝试使用过期的缓存作为降级方案
if (!force) {