tgf / internal /commands /admin.go
Mohammad Shahid
added user managment
aa300d8
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
}