add load more command
This commit is contained in:
+72
-18
@@ -12,18 +12,20 @@ import (
|
||||
"git.vakhrushev.me/av/remembos/internal/config"
|
||||
"git.vakhrushev.me/av/remembos/internal/memory"
|
||||
"git.vakhrushev.me/av/remembos/internal/memos"
|
||||
"git.vakhrushev.me/av/remembos/internal/search"
|
||||
)
|
||||
|
||||
// Bot sends a daily memory via Telegram.
|
||||
type Bot struct {
|
||||
api *tgbotapi.BotAPI
|
||||
service *memory.Service
|
||||
client *memos.Client
|
||||
chatID int64
|
||||
sendAt string // "HH:MM"
|
||||
publicURL string
|
||||
loc *time.Location
|
||||
logger *slog.Logger
|
||||
api *tgbotapi.BotAPI
|
||||
service *memory.Service
|
||||
client *memos.Client
|
||||
chatID int64
|
||||
sendAt string // "HH:MM"
|
||||
publicURL string
|
||||
loc *time.Location
|
||||
logger *slog.Logger
|
||||
allowLoadMore bool
|
||||
}
|
||||
|
||||
// NewBot creates a new Telegram bot.
|
||||
@@ -32,6 +34,7 @@ func NewBot(
|
||||
service *memory.Service,
|
||||
client *memos.Client,
|
||||
memosURL, publicURL string,
|
||||
allowLoadMore bool,
|
||||
loc *time.Location,
|
||||
logger *slog.Logger,
|
||||
) (*Bot, error) {
|
||||
@@ -49,19 +52,24 @@ func NewBot(
|
||||
logger.Info("telegram bot authorized", "username", api.Self.UserName)
|
||||
|
||||
return &Bot{
|
||||
api: api,
|
||||
service: service,
|
||||
client: client,
|
||||
chatID: cfg.ChatID,
|
||||
sendAt: cfg.SendAt,
|
||||
publicURL: pub,
|
||||
loc: loc,
|
||||
logger: logger,
|
||||
api: api,
|
||||
service: service,
|
||||
client: client,
|
||||
chatID: cfg.ChatID,
|
||||
sendAt: cfg.SendAt,
|
||||
publicURL: pub,
|
||||
loc: loc,
|
||||
logger: logger,
|
||||
allowLoadMore: allowLoadMore,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Run starts the scheduling loop. It blocks until ctx is cancelled.
|
||||
func (b *Bot) Run(ctx context.Context) {
|
||||
if b.allowLoadMore {
|
||||
go b.listenForCommands(ctx)
|
||||
}
|
||||
|
||||
for {
|
||||
next := b.nextSendTime()
|
||||
delay := time.Until(next)
|
||||
@@ -105,15 +113,20 @@ func (b *Bot) sendDaily(ctx context.Context) {
|
||||
b.logger.Error("failed to get today memory", "error", err)
|
||||
return
|
||||
}
|
||||
|
||||
b.sendMemory(ctx, mem)
|
||||
}
|
||||
|
||||
// sendMemory formats and sends a memory via Telegram.
|
||||
func (b *Bot) sendMemory(ctx context.Context, mem *search.Memory) {
|
||||
if mem == nil {
|
||||
b.logger.Info("no memory for today, skipping telegram send")
|
||||
b.logger.Info("no memory to send, skipping")
|
||||
return
|
||||
}
|
||||
|
||||
mainText, captionText := formatMemory(mem, b.publicURL)
|
||||
images := imageAttachments(mem.Memo)
|
||||
|
||||
// Try to download images
|
||||
var downloaded []imageFile
|
||||
if len(images) > 0 {
|
||||
downloaded = b.downloadImages(ctx, images)
|
||||
@@ -124,6 +137,47 @@ func (b *Bot) sendDaily(ctx context.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
// listenForCommands polls for Telegram updates and handles /more commands.
|
||||
func (b *Bot) listenForCommands(ctx context.Context) {
|
||||
u := tgbotapi.NewUpdate(0)
|
||||
u.Timeout = 60
|
||||
|
||||
updates := b.api.GetUpdatesChan(u)
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case update, ok := <-updates:
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
if update.Message == nil || !update.Message.IsCommand() {
|
||||
continue
|
||||
}
|
||||
if update.Message.Chat.ID != b.chatID {
|
||||
continue
|
||||
}
|
||||
if update.Message.Command() == "more" {
|
||||
b.handleMore(ctx)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// handleMore loads a new memory and sends it.
|
||||
func (b *Bot) handleMore(ctx context.Context) {
|
||||
b.logger.Info("handling /more command")
|
||||
|
||||
mem, err := b.service.LoadNewMemory(ctx)
|
||||
if err != nil {
|
||||
b.logger.Error("failed to load new memory", "error", err)
|
||||
return
|
||||
}
|
||||
|
||||
b.sendMemory(ctx, mem)
|
||||
}
|
||||
|
||||
type imageFile struct {
|
||||
filename string
|
||||
data []byte
|
||||
|
||||
Reference in New Issue
Block a user