tgf / internal /commands /batch.go
Mohammad Shahid
added user managment
aa300d8
// In file: internal/commands/batch.go
package commands
import (
"TelegramCloud/tgf/internal/state"
"TelegramCloud/tgf/internal/utils"
"fmt"
"math/rand"
"strings"
"time"
"github.com/celestix/gotgproto/dispatcher"
"github.com/celestix/gotgproto/dispatcher/handlers"
"github.com/celestix/gotgproto/ext"
"github.com/gotd/td/telegram/message/styling"
"github.com/gotd/td/tg"
"go.uber.org/zap"
)
func (m *command) LoadBatch(dispatcher dispatcher.Dispatcher) {
log := m.log.Named("batch")
defer log.Sugar().Info("Loaded stateful batch commands")
dispatcher.AddHandler(handlers.NewCommand("batch", batchStart))
dispatcher.AddHandler(handlers.NewCommand("done", batchDone))
dispatcher.AddHandler(handlers.NewCommand("cancel", batchCancel))
}
// _activateBatchMode is a helper to enter batch mode and send the confirmation message.
func _activateBatchMode(ctx *ext.Context, u *ext.Update) error {
// FIX: Define the logger for this function's scope.
log := utils.Logger.Named("activateBatchMode")
userID := u.EffectiveUser().ID
state.GlobalStateManager.EnterBatchMode(userID)
msg := `✅ **Batch mode activated.**
Send me all the files you want to process. I will collect them without sending immediate replies.
When you are finished, send /done to get the final list of links.
To abort, send /cancel.`
if u.CallbackQuery != nil {
peer := ctx.PeerStorage.GetInputPeerById(u.CallbackQuery.UserID)
_, err := ctx.Raw.MessagesSendMessage(ctx, &tg.MessagesSendMessageRequest{
Peer: peer,
Message: msg,
RandomID: rand.Int63(),
NoWebpage: true,
})
if err != nil {
log.Error("Failed to send batch activation message", zap.Error(err))
}
} else {
ctx.Reply(u, msg, nil)
}
return dispatcher.EndGroups
}
func batchStart(ctx *ext.Context, u *ext.Update) error {
return _activateBatchMode(ctx, u)
}
func batchCancel(ctx *ext.Context, u *ext.Update) error {
userID := u.EffectiveUser().ID
if !state.GlobalStateManager.IsUserInBatch(userID) {
ctx.Reply(u, "You are not in batch mode.", nil)
return dispatcher.EndGroups
}
state.GlobalStateManager.ExitBatchMode(userID)
ctx.Reply(u, "❌ Batch cancelled.", nil)
return dispatcher.EndGroups
}
func batchDone(ctx *ext.Context, u *ext.Update) error {
log := utils.Logger.Named("batchDone")
userID := u.EffectiveUser().ID
if !state.GlobalStateManager.IsUserInBatch(userID) {
ctx.Reply(u, "You are not in batch mode. Start a new one with /batch.", nil)
return dispatcher.EndGroups
}
filesToProcess := state.GlobalStateManager.GetAndClearFiles(userID)
if len(filesToProcess) == 0 {
ctx.Reply(u, "You haven't sent any files in this batch. Batch cancelled.", nil)
return dispatcher.EndGroups
}
statusMsg, _ := ctx.Reply(u, fmt.Sprintf("Processing %d files... Please wait.", len(filesToProcess)), nil)
peer := u.EffectiveChat().GetInputPeer()
editStatus := func(text string) {
req := &tg.MessagesEditMessageRequest{Peer: peer, ID: statusMsg.ID, Message: text}
_, _ = ctx.Raw.MessagesEditMessage(ctx, req)
}
var links []string
totalFiles := len(filesToProcess)
for i, msgID := range filesToProcess {
editStatus(fmt.Sprintf("Processing file %d of %d...", i+1, totalFiles))
link, _, err := utils.GenerateStreamLink(ctx, u, msgID)
if err != nil {
log.Error("Error generating link for message in batch", zap.Error(err), zap.Int("messageID", msgID))
links = append(links, fmt.Sprintf("Error processing message ID %d: %s", msgID, err.Error()))
} else {
links = append(links, link)
}
time.Sleep(500 * time.Millisecond)
}
const telegramMessageLimit = 4000
linkBlock := strings.Join(links, "\n")
header := fmt.Sprintf("✅ Batch complete! Here are the %d links.\n\nCopy the text below and paste it into your download manager (IDM, 1DM, etc.):", totalFiles)
ctx.DeleteMessages(u.EffectiveChat().GetID(), []int{statusMsg.ID})
if len(header)+len(linkBlock) < telegramMessageLimit {
messageTextWithOptions := []styling.StyledTextOption{
styling.Plain(header), styling.Plain("\n\n"), styling.Code(linkBlock),
}
ctx.Reply(u, messageTextWithOptions, &ext.ReplyOpts{ReplyToMessageId: u.EffectiveMessage.ID})
} else {
ctx.Reply(u,
fmt.Sprintf("Batch complete with %d files, but the list of links is too long to send in a single message.", totalFiles),
&ext.ReplyOpts{ReplyToMessageId: u.EffectiveMessage.ID},
)
}
return dispatcher.EndGroups
}