Files
mygoTgChanBot/internal/telegram/handlers_entry.go
2026-02-05 21:29:48 +08:00

173 lines
4.7 KiB
Go
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package telegram
import (
"fmt"
"html"
"strconv"
"strings"
tele "gopkg.in/telebot.v3"
)
const (
cbPrefixDelEntry = "del:"
cbPrefixDelWithMsg = "delwithmsg:"
cbPrefixDelOnlyToc = "delonlytoc:"
)
func (b *Bot) handleEntryDel(c tele.Context) error {
id := strings.TrimSpace(c.Message().Payload)
if id == "" {
return c.Reply("用法: /del <ID>")
}
entry, err := b.storage.GetEntry(id)
if err != nil {
return c.Reply(fmt.Sprintf("❌ %v", err))
}
menu := &tele.ReplyMarkup{}
delWithMsgBtn := menu.Data("🗑 删除条目+频道消息", cbPrefixDelWithMsg+id)
delOnlyTocBtn := menu.Data("📝 仅删除目录条目", cbPrefixDelOnlyToc+id)
cancelBtn := menu.Data("❌ 取消", cbCancel)
menu.Inline(
menu.Row(delWithMsgBtn),
menu.Row(delOnlyTocBtn),
menu.Row(cancelBtn),
)
text := fmt.Sprintf("🗑 确认删除?\n\n分类: %s\n标题: %s\n\n请选择删除方式:", entry.Category, entry.Title)
return c.Reply(text, menu)
}
func (b *Bot) handleEntryEdit(c tele.Context) error {
args := strings.SplitN(c.Message().Payload, " ", 2)
if len(args) < 2 {
return c.Reply("用法: /edit <ID> <新标题>")
}
id := args[0]
newTitle := strings.TrimSpace(args[1])
if err := b.storage.UpdateEntryTitle(id, newTitle); err != nil {
return c.Reply(fmt.Sprintf("❌ %v", err))
}
b.toc.TriggerUpdate()
return c.Reply(fmt.Sprintf("✅ 标题已更新为: %s", newTitle))
}
func (b *Bot) handleEntryMove(c tele.Context) error {
args := strings.Fields(c.Message().Payload)
if len(args) < 2 {
return c.Reply("用法: /move <ID> <新分类>")
}
id := args[0]
newCategory := args[1]
if !b.storage.CategoryExists(newCategory) {
return c.Reply(fmt.Sprintf("❌ 分类 [%s] 不存在", newCategory))
}
if err := b.storage.UpdateEntryCategory(id, newCategory); err != nil {
return c.Reply(fmt.Sprintf("❌ %v", err))
}
b.toc.TriggerUpdate()
return c.Reply(fmt.Sprintf("✅ 已移动到分类: %s", newCategory))
}
func (b *Bot) handleEntryList(c tele.Context) error {
category := strings.TrimSpace(c.Message().Payload)
entries, err := b.storage.ListEntries(category)
if err != nil {
return c.Reply(fmt.Sprintf("❌ %v", err))
}
if len(entries) == 0 {
if category != "" {
return c.Reply(fmt.Sprintf("📭 分类 [%s] 暂无条目", category))
}
return c.Reply("📭 暂无条目")
}
var sb strings.Builder
if category != "" {
sb.WriteString(fmt.Sprintf("📋 分类 [%s] 的条目:\n\n", html.EscapeString(category)))
} else {
sb.WriteString("📋 所有条目:\n\n")
}
currentCat := ""
for _, e := range entries {
if category == "" && e.Category != currentCat {
currentCat = e.Category
sb.WriteString(fmt.Sprintf("\n【%s】\n", html.EscapeString(currentCat)))
}
sb.WriteString(fmt.Sprintf("• <code>%s</code> %s\n", e.ID, html.EscapeString(e.Title)))
}
return c.Reply(sb.String(), tele.ModeHTML)
}
func (b *Bot) handleRefresh(c tele.Context) error {
b.toc.TriggerUpdate()
return c.Reply("🔄 目录刷新已触发")
}
// handleDeleteEntryCallback 处理删除条目的回调
func (b *Bot) handleDeleteEntryCallback(c tele.Context, entryID string, deleteChannelMsg bool) error {
entry, err := b.storage.GetEntry(entryID)
if err != nil {
c.Edit(fmt.Sprintf("❌ %v", err))
return c.Respond(&tele.CallbackResponse{Text: "条目不存在"})
}
// 根据用户选择决定是否删除频道消息
msgDeleted := false
if deleteChannelMsg {
if msgID := parseMessageIDFromLink(entry.Link); msgID != 0 {
channel := &tele.Chat{ID: b.cfg.Channel.ID}
msg := &tele.Message{ID: msgID, Chat: channel}
if err := b.bot.Delete(msg); err == nil {
msgDeleted = true
}
}
}
if err := b.storage.DeleteEntry(entryID); err != nil {
c.Edit(fmt.Sprintf("❌ 删除失败: %v", err))
return c.Respond(&tele.CallbackResponse{Text: "删除失败"})
}
b.toc.TriggerUpdate()
var text string
if deleteChannelMsg && msgDeleted {
text = fmt.Sprintf("✅ 已删除: [%s] %s\n📨 频道消息已同步删除", entry.Category, entry.Title)
} else if deleteChannelMsg && !msgDeleted {
text = fmt.Sprintf("✅ 已删除: [%s] %s\n⚠ 频道消息删除失败(可能已被删除)", entry.Category, entry.Title)
} else {
text = fmt.Sprintf("✅ 已删除: [%s] %s\n📝 频道消息已保留", entry.Category, entry.Title)
}
c.Edit(text)
return c.Respond(&tele.CallbackResponse{Text: "删除成功"})
}
// parseMessageIDFromLink 从链接中解析消息ID
// 支持格式: https://t.me/c/123456/789 或 https://t.me/username/789
func parseMessageIDFromLink(link string) int {
parts := strings.Split(link, "/")
if len(parts) < 1 {
return 0
}
msgID, err := strconv.Atoi(parts[len(parts)-1])
if err != nil {
return 0
}
return msgID
}