package telegram import ( "log" "time" "tgchanbot/internal/config" "tgchanbot/internal/storage" "tgchanbot/internal/toc" tele "gopkg.in/telebot.v3" ) type Bot struct { bot *tele.Bot cfg *config.Config storage *storage.Storage toc *toc.Manager states *StateManager } func New(cfg *config.Config, store *storage.Storage) (*Bot, error) { pref := tele.Settings{ Token: cfg.Bot.Token, Poller: &tele.LongPoller{Timeout: 10 * time.Second}, } b, err := tele.NewBot(pref) if err != nil { return nil, err } bot := &Bot{ bot: b, cfg: cfg, storage: store, states: NewStateManager(), } bot.toc = toc.NewManager(store, b, cfg.Channel.ID, time.Duration(cfg.TOC.DebounceSeconds)*time.Second) bot.setupRoutes() return bot, nil } func (b *Bot) setupRoutes() { adminOnly := b.bot.Group() adminOnly.Use(b.AdminMiddleware()) // Category management adminOnly.Handle("/cat_add", b.handleCatAdd) adminOnly.Handle("/cat_del", b.handleCatDel) adminOnly.Handle("/cat_list", b.handleCatList) // Post flow adminOnly.Handle("/post", b.handlePost) adminOnly.Handle(tele.OnText, b.handleTextInput) adminOnly.Handle(tele.OnPhoto, b.handleTextInput) adminOnly.Handle(tele.OnVideo, b.handleTextInput) adminOnly.Handle(tele.OnDocument, b.handleTextInput) adminOnly.Handle(tele.OnAudio, b.handleTextInput) adminOnly.Handle(tele.OnVoice, b.handleTextInput) adminOnly.Handle(tele.OnAnimation, b.handleTextInput) adminOnly.Handle(tele.OnSticker, b.handleTextInput) // Entry management adminOnly.Handle("/del", b.handleEntryDel) adminOnly.Handle("/edit", b.handleEntryEdit) adminOnly.Handle("/move", b.handleEntryMove) adminOnly.Handle("/list", b.handleEntryList) // TOC adminOnly.Handle("/refresh", b.handleRefresh) // Admin management (super admin only) superAdminOnly := b.bot.Group() superAdminOnly.Use(b.SuperAdminMiddleware()) superAdminOnly.Handle("/admin_add", b.handleAdminAdd) superAdminOnly.Handle("/admin_del", b.handleAdminDel) superAdminOnly.Handle("/admin_list", b.handleAdminList) // Callbacks b.bot.Handle(tele.OnCallback, b.handleCallback) } func (b *Bot) Start() { b.setCommands() log.Println("Bot started...") b.bot.Start() } func (b *Bot) setCommands() { commands := []tele.Command{ {Text: "post", Description: "投稿 - 添加频道内容到目录"}, {Text: "list", Description: "列表 - 查看所有条目"}, {Text: "cat_list", Description: "分类列表"}, {Text: "cat_add", Description: "添加分类 <名称> [排序]"}, {Text: "cat_del", Description: "删除分类 <名称>"}, {Text: "del", Description: "删除条目 "}, {Text: "edit", Description: "编辑标题 <新标题>"}, {Text: "move", Description: "移动条目 <新分类>"}, {Text: "refresh", Description: "刷新目录"}, } if err := b.bot.SetCommands(commands); err != nil { log.Printf("Failed to set commands: %v", err) } } func (b *Bot) Stop() { b.bot.Stop() b.toc.Stop() }