diff --git a/main.go b/main.go index c0e632e..c4f591a 100644 --- a/main.go +++ b/main.go @@ -99,10 +99,40 @@ func onVoiceStateUpdate(s *discordgo.Session, e *discordgo.VoiceStateUpdate) { return } - // User rüber bewegen - if moveErr := s.GuildMemberMove(e.GuildID, e.UserID, &newChan.ID); moveErr != nil { - log.Printf("Move fehlgeschlagen: %v", moveErr) - } + // User rüber bewegen (mit Perm-Check & Retry) + go func() { + // kurz warten, bis Discord den neuen Channel „fertig“ hat + time.Sleep(200 * time.Millisecond) + + // Check: hat der Bot Move Members in Lobby & Ziel? + if perms, err := s.UserChannelPermissions(s.State.User.ID, e.ChannelID); err == nil { + need := int64(discordgo.PermissionVoiceMoveMembers) + if perms&need == 0 { + log.Printf("WARN: Bot hat im Lobby-Channel keine MoveMembers-Permission") + } + } + if perms, err := s.UserChannelPermissions(s.State.User.ID, newChan.ID); err == nil { + need := int64(discordgo.PermissionVoiceMoveMembers) + if perms&need == 0 { + log.Printf("WARN: Bot hat im Ziel-Channel keine MoveMembers-Permission") + } + } + + // bis zu 5 Versuche mit steigendem Backoff + var moveErr error + for attempt := 0; attempt < 5; attempt++ { + moveErr = s.GuildMemberMove(e.GuildID, e.UserID, &newChan.ID) + if moveErr == nil { + break + } + wait := time.Duration(150*(attempt+1)) * time.Millisecond + log.Printf("Move fehlgeschlagen (Versuch %d): %v - retry in %s", attempt+1, moveErr, wait) + time.Sleep(wait) + } + if moveErr != nil { + log.Printf("Move endgültig fehlgeschlagen: %v", moveErr) + } + }() // Auto-Cleanup starten go watchAndCleanup(s, e.GuildID, newChan.ID, time.Duration(timeoutMin)*time.Minute) @@ -184,6 +214,9 @@ func onInteractionCreate(categoryID string) func(s *discordgo.Session, i *discor var name string userLimit := 0 timeoutMin := 60 + if v := os.Getenv("TIMEOUT_MIN"); v != "" { + fmt.Sscanf(v, "%d", &timeoutMin) + } for _, o := range i.ApplicationCommandData().Options { switch o.Name { case "name":