Multiple meeting lobbies and beta-gated features (3.5.2)

- /meeting add-lobby, remove-lobby, lobbies: up to 10 lobbies per server, capped in the database
- Deleted voice channels are dropped from the lobbies
- Beta features: registered only in the beta server and usable only with the Beta Tester role (BETA_GUILD_ID, BETA_ROLE_ID); fails closed
- /beta (bot owner only) shows how beta access is set up

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
This commit is contained in:
FernandoJVideiraandClaude Sonnet 5.5 committed 2026-10-23 00:38:48 +01:00
1 parent 136377d81a
commit a364435bab
15 files changed
+789 -52

No files matched your search

+23 -4
View File
@@ -13,7 +13,7 @@ import (
)
// HandleVoiceStateUpdate implements the "meeting lobby" behavior:
// - When a user joins the configured lobby voice channel, create a temporary voice channel
// - When a user joins one of the server's lobby voice channels, create a temporary voice channel
// with the same UserLimit and move the user into it.
// - When a temporary channel becomes empty, delete it.
func HandleVoiceStateUpdate(s *discordgo.Session, vs *discordgo.VoiceStateUpdate, svc *services.Services) {
@@ -40,11 +40,12 @@ func HandleVoiceStateUpdate(s *discordgo.Session, vs *discordgo.VoiceStateUpdate
return
}
lobbyID, ok, err := svc.Meeting.GetLobbyChannel(ctx, guildID64)
if err != nil || !ok || lobbyID == 0 {
joinedID, err := strconv.ParseInt(vs.ChannelID, 10, 64)
if err != nil {
return
}
if vs.ChannelID != strconv.FormatInt(lobbyID, 10) {
isLobby, err := svc.Meeting.IsLobby(ctx, guildID64, joinedID)
if err != nil || !isLobby {
return
}
@@ -114,3 +115,21 @@ func tryCleanupTempChannel(s *discordgo.Session, ctx context.Context, svc *servi
_ = svc.Meeting.RemoveTempChannel(ctx, guildID64, chID64)
}
// HandleChannelDelete drops a deleted voice channel from the meeting lobbies,
// so it doesn't keep using up one of the server's slots.
func HandleChannelDelete(_ *discordgo.Session, c *discordgo.ChannelDelete, svc *services.Services) {
if svc == nil || svc.Meeting == nil || c == nil || c.Channel == nil || c.GuildID == "" {
return
}
if c.Type != discordgo.ChannelTypeGuildVoice {
return
}
guildID, err1 := strconv.ParseInt(c.GuildID, 10, 64)
channelID, err2 := strconv.ParseInt(c.ID, 10, 64)
if err1 != nil || err2 != nil {
return
}
if _, err := svc.Meeting.RemoveLobby(context.Background(), guildID, channelID); err != nil {
log.Printf("meeting: removing deleted lobby guild=%s channel=%s err=%v", c.GuildID, c.ID, err)
}
}