package bot import ( "log" "velox-bot/internal/commands" "velox-bot/internal/db/services" "velox-bot/internal/events" "velox-bot/internal/music" "github.com/bwmarrin/discordgo" ) type Bot struct { Session *discordgo.Session AppID string GuildID string Commands []*discordgo.ApplicationCommand registeredCommands []*discordgo.ApplicationCommand Services *services.Services LavalinkHost string LavalinkPass string } func NewBot(token, appID, guildID, lavalinkHost, lavalinkPass string, cmds []*discordgo.ApplicationCommand, services *services.Services) (*Bot, error) { session, err := discordgo.New("Bot " + token) if err != nil { return nil, err } // Intents needed for: // - InteractionCreate (slash commands): Guilds // - MessageCreate (leveling): GuildMessages // - VoiceStateUpdate (meeting lobby): GuildVoiceStates session.Identify.Intents = discordgo.IntentsGuilds | discordgo.IntentsGuildMessages | discordgo.IntentsGuildVoiceStates return &Bot{ Session: session, AppID: appID, GuildID: guildID, Commands: cmds, Services: services, LavalinkHost: lavalinkHost, LavalinkPass: lavalinkPass, }, nil } func (b *Bot) Start() error { if err := b.Session.Open(); err != nil { return err } _ = music.Init(b.Session, b.AppID, b.LavalinkHost, b.LavalinkPass) b.registeredCommands = make([]*discordgo.ApplicationCommand, len(b.Commands)) for _, cmd := range b.Commands { created, err := b.Session.ApplicationCommandCreate(b.AppID, b.GuildID, cmd) if err != nil { log.Printf("Cannot create '%v' command: %v", cmd.Name, err) continue } b.registeredCommands = append(b.registeredCommands, created) } b.Session.AddHandler(commands.HandleInteraction) b.Session.AddHandler(func(s *discordgo.Session, m *discordgo.MessageCreate) { events.HandleMessageCreate(s, m, b.Services) }) b.Session.AddHandler(func(s *discordgo.Session, vs *discordgo.VoiceStateUpdate) { events.HandleVoiceStateUpdate(s, vs, b.Services) music.OnVoiceStateUpdate(vs) }) b.Session.AddHandler(func(s *discordgo.Session, ev *discordgo.VoiceServerUpdate) { music.OnVoiceServerUpdate(ev) }) return nil } func (b *Bot) Close() error { for _, cmd := range b.registeredCommands { if err := b.Session.ApplicationCommandDelete(b.AppID, b.GuildID, cmd.ID); err != nil { log.Printf("cannot delete '%s' command: %v", cmd.Name, err) } } return b.Session.Close() }