Spaces:
Paused
Paused
| // 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 | |
| } |