package toc import ( "log" "sync" "time" "tgchanbot/internal/storage" tele "gopkg.in/telebot.v3" ) type Manager struct { storage *storage.Storage bot *tele.Bot chanID int64 debounce time.Duration mu sync.Mutex pending bool timer *time.Timer stopCh chan struct{} } func NewManager(store *storage.Storage, bot *tele.Bot, chanID int64, debounce time.Duration) *Manager { return &Manager{ storage: store, bot: bot, chanID: chanID, debounce: debounce, stopCh: make(chan struct{}), } } func (m *Manager) TriggerUpdate() { m.mu.Lock() defer m.mu.Unlock() m.pending = true if m.timer != nil { m.timer.Stop() } m.timer = time.AfterFunc(m.debounce, func() { m.doUpdate() }) } func (m *Manager) doUpdate() { m.mu.Lock() m.pending = false m.mu.Unlock() content, err := m.Render() if err != nil { log.Printf("TOC render error: %v", err) return } if err := m.updateMessage(content); err != nil { log.Printf("TOC update error: %v", err) } } func (m *Manager) updateMessage(content string) error { chat := &tele.Chat{ID: m.chanID} msgID, err := m.storage.GetTocMsgID() if err != nil { return err } if msgID == 0 { msg, err := m.bot.Send(chat, content, tele.ModeMarkdown, tele.NoPreview) if err != nil { return err } return m.storage.SetTocMsgID(msg.ID) } existingMsg := &tele.Message{ ID: msgID, Chat: chat, } _, err = m.bot.Edit(existingMsg, content, tele.ModeMarkdown, tele.NoPreview) if err != nil { if err == tele.ErrMessageNotModified { return nil } if err.Error() == "telegram: message to edit not found (400)" { msg, err := m.bot.Send(chat, content, tele.ModeMarkdown, tele.NoPreview) if err != nil { return err } return m.storage.SetTocMsgID(msg.ID) } return err } return nil } func (m *Manager) Stop() { m.mu.Lock() defer m.mu.Unlock() if m.timer != nil { m.timer.Stop() } close(m.stopCh) }