DisGoLink is a Lavalink Client written in Golang which supports the latest Lavalink 4.0.0+ release and the new plugin system.
While DisGoLink can be used with any Discord Library DisGo is the best fit for it as usage with other Libraries can be a bit annoying due to different Snowflake implementations.
This Library uses the Disgo Snowflake package like DisGo
go get github.com/disgoorg/disgolink/v3
First create a new lavalink instance. You can do this either with
import (
"github.com/disgoorg/snowflake/v2"
"github.com/disgoorg/disgolink/v3/disgolink"
)
var userID = snowflake.ID(1234567890)
lavalinkClient := disgolink.New(userID)
You also need to forward the VOICE_STATE_UPDATE
and VOICE_SERVER_UPDATE
events to DisGoLink.
Just register an event listener for those events with your library and call lavalinkClient.OnVoiceStateUpdate
(make sure to only forward your bots voice update event!) and lavalinkClient.OnVoiceServerUpdate
For DisGo this would look like this
client, err := disgo.New(Token,
bot.WithEventListenerFunc(b.onVoiceStateUpdate),
bot.WithEventListenerFunc(b.onVoiceServerUpdate),
)
func onVoiceStateUpdate(event *events.GuildVoiceStateUpdate) {
// filter all non bot voice state updates out
if event.VoiceState.UserID != client.ApplicationID() {
return
}
lavalinkClient.OnVoiceStateUpdate(context.TODO(), event.VoiceState.GuildID, event.VoiceState.ChannelID, event.VoiceState.SessionID)
}
func onVoiceServerUpdate(event *events.VoiceServerUpdate) {
lavalinkClient.OnVoiceServerUpdate(context.TODO(), event.GuildID, event.Token, *event.Endpoint)
}
Then you add your lavalink nodes. This directly connects to the nodes and is a blocking call
node, err := lavalinkClient.AddNode(context.TODO(), lavalink.NodeConfig{
Name: "test", // a unique node name
Address: "localhost:2333",
Password: "youshallnotpass",
Secure: false, // ws or wss
SessionID: "", // only needed if you want to resume a previous lavalink session
})
after this you can play songs from lavalinks supported sources.
To play a track you first need to resolve the song. For this you need to call the Lavalink rest loadtracks
endpoint which returns a result with various track instances. Those tracks can then be played.
query := "ytsearch:Rick Astley - Never Gonna Give You Up"
var toPlay *lavalink.Track
lavalinkClient.BestNode().LoadTracksHandler(context.TODO(), query, disgolink.NewResultHandler(
func(track lavalink.Track) {
// Loaded a single track
toPlay = &track
},
func(playlist lavalink.Playlist) {
// Loaded a playlist
},
func(tracks []lavalink.Track) {
// Loaded a search result
},
func() {
// nothing matching the query found
},
func(err error) {
// something went wrong while loading the track
},
))
To play a track we first need to connect to the voice channel. Connecting to a voice channel differs with every lib but here are some quick usages with some
// DisGo
err := client.UpdateVoiceState(context.TODO(), guildID, channelID, false, false)
// DiscordGo
err := session.ChannelVoiceJoinManual(guildID, channelID, false, false)
after this you can get/create your player and play the track
player := lavalinkClient.Player("guild_id") // This will either return an existing or new player
// toPlay is from result handler in the example above
err := player.Update(context.TODO(), lavalink.WithTrack(*toPlay))
now audio should start playing
You can listen for following lavalink events
PlayerUpdateMessage
Emitted every x seconds (default 5) with the current player statePlayerPause
Emitted when the player is pausedPlayerResume
Emitted when the player is resumedTrackStart
Emitted when a track starts playingTrackEnd
Emitted when a track endsTrackException
Emitted when a track throws an exceptionTrackStuck
Emitted when a track gets stuckWebsocketClosed
Emitted when the voice gateway connection to lavalink is closed
for this add and event listener for each event to your Client
instance when you create it or with Client.AddEventListener
lavalinkClient := disgolink.New(userID,
disgolink.WithListenerFunc(onPlayerUpdate),
disgolink.WithListenerFunc(onPlayerPause),
disgolink.WithListenerFunc(onPlayerResume),
disgolink.WithListenerFunc(onTrackStart),
disgolink.WithListenerFunc(onTrackEnd),
disgolink.WithListenerFunc(onTrackException),
disgolink.WithListenerFunc(onTrackStuck),
disgolink.WithListenerFunc(onWebSocketClosed),
)
func onPlayerUpdate(player disgolink.Player, event lavalink.PlayerUpdateMessage) {
// do something with the event
}
func onPlayerPause(player disgolink.Player, event lavalink.PlayerPauseEvent) {
// do something with the event
}
func onPlayerResume(player disgolink.Player, event lavalink.PlayerResumeEvent) {
// do something with the event
}
func onTrackStart(player disgolink.Player, event lavalink.TrackStartEvent) {
// do something with the event
}
func onTrackEnd(player disgolink.Player, event lavalink.TrackEndEvent) {
// do something with the event
}
func onTrackException(player disgolink.Player, event lavalink.TrackExceptionEvent) {
// do something with the event
}
func onTrackStuck(player disgolink.Player, event lavalink.TrackStuckEvent) {
// do something with the event
}
func onWebSocketClosed(player disgolink.Player, event lavalink.WebSocketClosedEvent) {
// do something with the event
}
Lavalink added plugins in v3.5
. DisGoLink exposes a similar API for you to use. With that you can create plugins which require server & client work.
To see what you can do with plugins see here
You register plugins when creating the client instance like this
lavalinkClient := disgolink.New(userID, disgolink.WithPlugins(yourPlugin))
Here is a list of plugins(you can pr your own to here):
- SponsorBlock support for Lavalink Sponsorblock-Plugin
- LavaQueue support for Lavalink LavaQueue-Plugin
- LavaSrc support for Lavalink LavaSrc-Plugin
- LavaLyrics support for Lavalink LavaLyrics-Plugin
- LavaSearch support for Lavalink LavaSearch-Plugin
You can find examples under
For help feel free to open an issue or reach out on Discord
Contributions are welcomed but for bigger changes please first reach out via Discord or create an issue to discuss your intentions and ideas.