Spaces:
Paused
Paused
| 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 <user_id> <role>`" + ` | |
| **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 <user_id>`"+"\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 <user_id>`"+"\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 | |
| } | |