feat(music): consume playback commands via LISTEN/NOTIFY

The dashboard has been writing skip/pause/volume/etc. requests into
music_commands with nothing on this end reading them. Adds a
dedicated LISTEN connection (can't use the pooled *sql.DB for this,
LISTEN has to stay bound to one specific connection) that wakes on
NOTIFY, drains unprocessed rows, and dispatches each to the matching
Manager function. A command's error is logged, not fatal, and every
row gets marked processed regardless of outcome so a permanently
broken command doesn't retry forever.
This commit is contained in:
2026-08-29 19:22:16 +01:00
parent 7a17c55774
commit fcc7c9c66a
3 changed files with 117 additions and 2 deletions
+10 -1
View File
@@ -1,6 +1,7 @@
package bot
import (
"context"
"log"
"velox-bot/internal/commands"
"velox-bot/internal/db/repos/musicrepo"
@@ -19,11 +20,12 @@ type Bot struct {
registeredCommands []*discordgo.ApplicationCommand
Services *services.Services
MusicRepo *musicrepo.Repo
DBHost string
LavalinkHost string
LavalinkPass string
}
func NewBot(token, appID, guildID, lavalinkHost, lavalinkPass string, cmds []*discordgo.ApplicationCommand, services *services.Services, musicRepo *musicrepo.Repo) (*Bot, error) {
func NewBot(token, appID, guildID, lavalinkHost, lavalinkPass string, cmds []*discordgo.ApplicationCommand, services *services.Services, musicRepo *musicrepo.Repo, dbHost string) (*Bot, error) {
session, err := discordgo.New("Bot " + token)
if err != nil {
return nil, err
@@ -49,6 +51,7 @@ func NewBot(token, appID, guildID, lavalinkHost, lavalinkPass string, cmds []*di
Commands: cmds,
Services: services,
MusicRepo: musicRepo,
DBHost: dbHost,
LavalinkHost: lavalinkHost,
LavalinkPass: lavalinkPass,
}, nil
@@ -61,6 +64,12 @@ func (b *Bot) Start() error {
_ = music.Init(b.Session, b.MusicRepo, b.AppID, b.LavalinkHost, b.LavalinkPass)
go func() {
if err := music.StartCommandListener(context.Background(), b.DBHost, b.MusicRepo); err != nil {
log.Printf("music: command listener stopped: %v", err)
}
}()
b.registeredCommands = make([]*discordgo.ApplicationCommand, len(b.Commands))
for _, cmd := range b.Commands {
created, err := b.Session.ApplicationCommandCreate(b.AppID, b.GuildID, cmd)