package commands import ( "TelegramCloud/tgf/config" "TelegramCloud/tgf/internal/db" "TelegramCloud/tgf/internal/utils" "context" "fmt" "strconv" "strings" "github.com/celestix/gotgproto/dispatcher" "github.com/celestix/gotgproto/dispatcher/handlers" "github.com/celestix/gotgproto/ext" "github.com/gotd/td/telegram/message/styling" "go.uber.org/zap" ) func (m *command) LoadAdmin(dispatcher dispatcher.Dispatcher) { log := m.log.Named("admin") defer log.Sugar().Info("Loaded admin commands") dispatcher.AddHandler(handlers.NewCommand("promote", promoteHandler)) dispatcher.AddHandler(handlers.NewCommand("demote", demoteHandler)) dispatcher.AddHandler(handlers.NewCommand("ban", banHandler)) dispatcher.AddHandler(handlers.NewCommand("userinfo", userinfoHandler)) } func promoteHandler(ctx *ext.Context, u *ext.Update) error { log := utils.Logger.Named("promoteHandler") adminID := u.EffectiveUser().ID // Check if user is admin if !isUserAdmin(adminID) { ctx.Reply(u, "❌ You don't have permission to use this command.", nil) return dispatcher.EndGroups } // Check if database is available if db.UserMgr == nil { ctx.Reply(u, "❌ Admin commands are currently unavailable. Database not connected.", nil) return dispatcher.EndGroups } // Parse command arguments args := strings.Fields(u.EffectiveMessage.GetMessage()) if len(args) < 3 { helpText := `👑 **Promote User** Usage: ` + "`/promote `" + ` **Available roles:** • ` + "`basic`" + ` - Basic user (default limits) • ` + "`premium`" + ` - Premium user (higher limits) • ` + "`admin`" + ` - Administrator (unlimited) **Example:** ` + "`/promote 123456789 premium`" + `` styledMessage := []styling.StyledTextOption{ styling.Plain(helpText), } ctx.Reply(u, styledMessage, nil) return dispatcher.EndGroups } // Parse user ID userID, err := strconv.ParseInt(args[1], 10, 64) if err != nil { ctx.Reply(u, "❌ Invalid user ID. Please provide a valid numeric user ID.", nil) return dispatcher.EndGroups } // Parse role role := strings.ToLower(args[2]) if role != db.RoleBasic && role != db.RolePremium && role != db.RoleAdmin { ctx.Reply(u, "❌ Invalid role. Available roles: basic, premium, admin", nil) return dispatcher.EndGroups } // Promote user err = db.UserMgr.PromoteUser(context.Background(), userID, role) if err != nil { log.Error("Failed to promote user", zap.Error(err)) ctx.Reply(u, "❌ Failed to promote user. Please try again later.", nil) return dispatcher.EndGroups } // Get updated user stats to show limits stats, err := db.UserMgr.GetOrCreateUserStats(context.Background(), userID) if err != nil { log.Error("Failed to get user stats after promotion", zap.Error(err)) ctx.Reply(u, fmt.Sprintf("✅ User %d has been promoted to **%s** role.", userID, role), nil) return dispatcher.EndGroups } roleEmoji := "👤" switch role { case db.RolePremium: roleEmoji = "⭐" case db.RoleAdmin: roleEmoji = "👑" } limitsText := fmt.Sprintf("Daily: %d, Monthly: %d", stats.DailyLimit, stats.MonthlyLimit) if role == db.RoleAdmin { limitsText = "Unlimited" } successText := fmt.Sprintf(`✅ **User Promoted Successfully** 👤 **User ID:** %d %s **New Role:** %s 📊 **New Limits:** %s The user will see updated limits in their next ` + "`/stats`" + ` command.`, userID, roleEmoji, role, limitsText, ) styledMessage := []styling.StyledTextOption{ styling.Plain(successText), } ctx.Reply(u, styledMessage, nil) return dispatcher.EndGroups } func demoteHandler(ctx *ext.Context, u *ext.Update) error { log := utils.Logger.Named("demoteHandler") adminID := u.EffectiveUser().ID // Check if user is admin if !isUserAdmin(adminID) { ctx.Reply(u, "❌ You don't have permission to use this command.", nil) return dispatcher.EndGroups } // Check if database is available if db.UserMgr == nil { ctx.Reply(u, "❌ Admin commands are currently unavailable. Database not connected.", nil) return dispatcher.EndGroups } // Parse command arguments args := strings.Fields(u.EffectiveMessage.GetMessage()) if len(args) < 2 { ctx.Reply(u, "Usage: "+"`/demote `"+"\n\nThis will demote the user to basic role.", nil) return dispatcher.EndGroups } // Parse user ID userID, err := strconv.ParseInt(args[1], 10, 64) if err != nil { ctx.Reply(u, "❌ Invalid user ID. Please provide a valid numeric user ID.", nil) return dispatcher.EndGroups } // Demote user to basic role err = db.UserMgr.PromoteUser(context.Background(), userID, db.RoleBasic) if err != nil { log.Error("Failed to demote user", zap.Error(err)) ctx.Reply(u, "❌ Failed to demote user. Please try again later.", nil) return dispatcher.EndGroups } successText := fmt.Sprintf("✅ User %d has been demoted to **basic** role with default limits.", userID) ctx.Reply(u, successText, nil) return dispatcher.EndGroups } func userinfoHandler(ctx *ext.Context, u *ext.Update) error { log := utils.Logger.Named("userinfoHandler") adminID := u.EffectiveUser().ID // Check if user is admin if !isUserAdmin(adminID) { ctx.Reply(u, "❌ You don't have permission to use this command.", nil) return dispatcher.EndGroups } // Check if database is available if db.UserMgr == nil { ctx.Reply(u, "❌ Admin commands are currently unavailable. Database not connected.", nil) return dispatcher.EndGroups } // Parse command arguments args := strings.Fields(u.EffectiveMessage.GetMessage()) if len(args) < 2 { ctx.Reply(u, "Usage: "+"`/userinfo `"+"\n\nGet detailed information about a user.", nil) return dispatcher.EndGroups } // Parse user ID userID, err := strconv.ParseInt(args[1], 10, 64) if err != nil { ctx.Reply(u, "❌ Invalid user ID. Please provide a valid numeric user ID.", nil) return dispatcher.EndGroups } // Get user stats stats, err := db.UserMgr.GetOrCreateUserStats(context.Background(), userID) if err != nil { log.Error("Failed to get user stats", zap.Error(err)) ctx.Reply(u, "❌ Failed to get user information. Please try again later.", nil) return dispatcher.EndGroups } // Get today's usage today := "2024-01-01" // You might want to use time.Now().Format("2006-01-02") dailyUsage, err := db.UserMgr.GetDailyUsage(context.Background(), userID, today) if err != nil { dailyUsage = &db.DailyUsage{FilesCount: 0, BandwidthUsed: 0} } // Format information roleEmoji := "👤" switch stats.Role { case db.RolePremium: roleEmoji = "⭐" case db.RoleAdmin: roleEmoji = "👑" } limitsText := fmt.Sprintf("Daily: %d, Monthly: %d", stats.DailyLimit, stats.MonthlyLimit) if stats.Role == db.RoleAdmin { limitsText = "Unlimited" } userInfoText := fmt.Sprintf(`👤 **User Information** 🆔 **User ID:** %d %s **Role:** %s 📊 **Limits:** %s **Statistics:** 📁 Files uploaded: %d 💾 Total storage: %s 📥 Total downloads: %d 🌐 Bandwidth used: %s **Today's Usage:** 📁 Files: %d 🌐 Bandwidth: %s **Account Info:** 📅 Member since: %s 🕒 Last active: %s`, userID, roleEmoji, stats.Role, limitsText, stats.FilesUploaded, formatBytes(stats.TotalSize), stats.TotalDownloads, formatBytes(stats.BandwidthUsed), dailyUsage.FilesCount, formatBytes(dailyUsage.BandwidthUsed), stats.CreatedAt.Format("Jan 2, 2006"), stats.LastActive.Format("Jan 2, 15:04"), ) styledMessage := []styling.StyledTextOption{ styling.Plain(userInfoText), } ctx.Reply(u, styledMessage, nil) return dispatcher.EndGroups } func banHandler(ctx *ext.Context, u *ext.Update) error { // This is a placeholder for ban functionality // You could implement this by adding a "banned" field to user stats ctx.Reply(u, "🚧 Ban functionality is not yet implemented.", nil) return dispatcher.EndGroups } // isUserAdmin checks if a user ID is an admin func isUserAdmin(userID int64) bool { // Check against bot owner or admin list from config // For now, we'll use a simple check - you can enhance this adminUsers := []int64{ // Add your admin user IDs here // config.ValueOf.BotOwnerID, // if you have this in config } // If no admin users configured, check if user is in allowed users and assume first one is admin if len(adminUsers) == 0 && len(config.ValueOf.AllowedUsers) > 0 { return userID == config.ValueOf.AllowedUsers[0] } for _, adminID := range adminUsers { if userID == adminID { return true } } return false }