Implement slash commands for playback control

This commit is contained in:
2026-09-21 18:48:17 +02:00
parent 347faf6b94
commit d05e721284
15 changed files with 809 additions and 0 deletions
+63
View File
@@ -0,0 +1,63 @@
package commands
import (
"context"
"errors"
"fmt"
"github.com/disgoorg/disgo/discord"
"github.com/disgoorg/disgo/events"
"discord-music-bot/internal/music"
)
type SeekCommand struct {
deps *Dependencies
}
func NewSeekCommand(deps *Dependencies) *SeekCommand {
return &SeekCommand{deps: deps}
}
func (c *SeekCommand) Definition() discord.ApplicationCommandCreate {
return discord.SlashCommandCreate{
Name: "seek",
Description: "Jumps to a position in the current track",
Options: []discord.ApplicationCommandOption{
discord.ApplicationCommandOptionString{
Name: "position",
Description: "Position to seek to: seconds, mm:ss or hh:mm:ss (e.g. 90 or 1:30)",
Required: true,
},
},
}
}
func (c *SeekCommand) Execute(ctx context.Context, event *events.ApplicationCommandInteractionCreate) error {
gid, err := requirePlaybackAccess(c.deps.Discord, event)
if err != nil {
return err
}
raw := event.SlashCommandInteractionData().String("position")
position, err := parsePosition(raw)
if err != nil {
return rejectEphemeral(event, fmt.Sprintf("Invalid position %q: %s", raw, err))
}
if err := c.deps.Music.Guild(gid).Seek(ctx, position); err != nil {
return replyWithError(event, seekErrorMessage(err), err)
}
return reply(event, fmt.Sprintf("Seeked to **%s**.", position))
}
func seekErrorMessage(err error) string {
switch {
case errors.Is(err, music.ErrNoTrackPlaying):
return "Nothing is playing right now."
case errors.Is(err, music.ErrStreamNotSeekable):
return "Can't seek within a live stream."
default:
return "Could not seek."
}
}