Add Discord client, command router and voice channel handling

This commit is contained in:
2026-09-21 18:48:11 +02:00
parent c4757933e1
commit 347faf6b94
4 changed files with 155 additions and 0 deletions
+79
View File
@@ -0,0 +1,79 @@
package discord
import (
"context"
"log/slog"
"github.com/disgoorg/disgo/bot"
"github.com/disgoorg/disgo/events"
"github.com/disgoorg/disgolink/v4/disgolink"
"discord-music-bot/internal/music"
)
type VoiceForwarder struct {
client *bot.Client
lavalink *disgolink.Client
music *music.Manager
logger *slog.Logger
}
func NewVoiceForwarder(client *bot.Client, lavalinkClient *disgolink.Client, musicManager *music.Manager, logger *slog.Logger) *VoiceForwarder {
return &VoiceForwarder{
client: client,
lavalink: lavalinkClient,
music: musicManager,
logger: logger,
}
}
func (f *VoiceForwarder) OnVoiceStateUpdate(event *events.GuildVoiceStateUpdate) {
if event.VoiceState.UserID == f.client.ApplicationID {
f.lavalink.OnVoiceStateUpdate(context.Background(), event.VoiceState.GuildID, event.VoiceState.ChannelID, event.VoiceState.SessionID)
return
}
f.leaveIfNowAlone(event)
}
func (f *VoiceForwarder) leaveIfNowAlone(event *events.GuildVoiceStateUpdate) {
oldChannelID := event.OldVoiceState.ChannelID
if oldChannelID == nil {
return
}
if newChannelID := event.VoiceState.ChannelID; newChannelID != nil && *newChannelID == *oldChannelID {
return
}
guildID := event.VoiceState.GuildID
botState, ok := f.client.Caches.VoiceState(guildID, f.client.ApplicationID)
if !ok || botState.ChannelID == nil || *botState.ChannelID != *oldChannelID {
return
}
for state := range f.client.Caches.VoiceStates(guildID) {
if state.UserID != f.client.ApplicationID && state.ChannelID != nil && *state.ChannelID == *oldChannelID {
return
}
}
ctx := context.Background()
if err := f.music.Guild(guildID).Stop(ctx); err != nil {
f.logger.ErrorContext(ctx, "failed to stop playback after being left alone",
slog.String("guild_id", guildID.String()), slog.Any("err", err))
}
if err := f.client.UpdateVoiceState(ctx, guildID, nil, false, false); err != nil {
f.logger.ErrorContext(ctx, "failed to leave voice channel after being left alone",
slog.String("guild_id", guildID.String()), slog.Any("err", err))
}
}
func (f *VoiceForwarder) OnVoiceServerUpdate(event *events.VoiceServerUpdate) {
if event.Endpoint == nil {
f.logger.Warn("received voice server update without an endpoint", slog.String("guild_id", event.GuildID.String()))
return
}
f.lavalink.OnVoiceServerUpdate(context.Background(), event.GuildID, event.Token, *event.Endpoint)
}