package main import ( "fmt" "log" "os" "os/signal" "syscall" "time" "github.com/bwmarrin/discordgo" "github.com/joho/godotenv" // WICHTIG: Pfad entspricht deiner go.mod "heydeman/vc-stat-bot-discord/db_management" ) var startTimes = make(map[string]time.Time) func main() { _ = godotenv.Load() // Ignoriert Fehler, falls keine .env existiert (nutzt dann System-Vars) db_management.InitDB() token := os.Getenv("DISCORD_TOKEN") if token == "" { log.Fatal("DISCORD_TOKEN nicht gefunden!") } discord, err := discordgo.New("Bot " + token) if err != nil { log.Fatal(err) } discord.AddHandler(messageCreate) discord.AddHandler(voiceUpdate) discord.Identify.Intents = discordgo.IntentsGuildMessages | discordgo.IntentsMessageContent | discordgo.IntentsGuildVoiceStates err = discord.Open() if err != nil { log.Fatal("Error opening connection:", err) } fmt.Println("Bot läuft stabil auf Hetzner. Drücke CTRL+C zum Beenden.") stop := make(chan os.Signal, 1) signal.Notify(stop, syscall.SIGINT, syscall.SIGTERM) <-stop // Graceful Shutdown: Alle aktuell aktiven Sessions noch schnell speichern fmt.Println("Speichere aktive Sessions vor dem Beenden...") for uid, start := range startTimes { db_management.SaveSession(uid, int(time.Since(start).Seconds())) } discord.Close() } func messageCreate(s *discordgo.Session, m *discordgo.MessageCreate) { if m.Author.Bot { return } if m.Content == "!stats" { totalSeconds := db_management.GetUserStats(m.Author.ID) duration := time.Duration(totalSeconds) * time.Second msg := fmt.Sprintf("📊 **30-Tage Statistik für %s**\nVerbrachte Zeit: `%s`", m.Author.GlobalName, formatDuration(duration)) s.ChannelMessageSend(m.ChannelID, msg) } } func voiceUpdate(s *discordgo.Session, v *discordgo.VoiceStateUpdate) { uid := v.UserID // User betritt Sprachkanal if v.ChannelID != "" { if _, ok := startTimes[uid]; !ok { startTimes[uid] = time.Now() } return } // User verlässt Sprachkanal (v.ChannelID == "") if v.ChannelID == "" { if start, ok := startTimes[uid]; ok { db_management.SaveSession(uid, int(time.Since(start).Seconds())) delete(startTimes, uid) } } } func formatDuration(d time.Duration) string { h := int(d.Hours()) m := int(d.Minutes()) % 60 s := int(d.Seconds()) % 60 return fmt.Sprintf("%dh %dm %ds", h, m, s) }