Shoukaku
A Lavalink wrapper for Discord.JS v12.x.x
The ShipGirl Project, feat Shoukaku; ⓒ Kancolle
Features
✅ Straightforward
✅ Stable
✅ Feature-rich
✅ Very cute shipgirl ❤ (Very Important)
Installation
For Lavalink Master
branch with commits no newer than https://github.com/Frederikam/Lavalink/commit/45f8de045fdd75034b75c63c410121d8315e6b75
npm i shoukaku@1.5.2
For Lavalink Dev
branch, or anything that doesn't fall into the scope of commits above
npm i shoukaku@1.6.x // Replace x with the latest semver patch available
If you live on the edge, and want any update available on Shoukaku
npm i Deivu/Shoukaku
Documentation
https://deivu.github.io/Shoukaku/?api
Changelogs
https://github.com/Deivu/Shoukaku/blob/master/CHANGELOGS.MD
Getting Lavalink
Download binaries from the CI server or the GitHub releases.
Put an application.yml file in your working directory.
Run with java -jar Lavalink.jar
Docker images are available on the Docker hub.
Other Links
Support | Lavalink
Example
Bot Implementation: https://github.com/Deivu/Kongou
Basic Implementation:
const { Client } = require('discord.js');
const { Shoukaku } = require('shoukaku');
const LavalinkServer = [{ name: 'Localhost', host: 'localhost', port: 6969, auth: 'big_weeb' }];
const ShoukakuOptions = { moveOnDisconnect: false, resumable: false, resumableTimeout: 30, reconnectTries: 2, restTimeout: 10000 };
class ExampleBot extends Client {
constructor(opts) {
super(opts);
this.shoukaku = new Shoukaku(this, LavalinkServer, ShoukakuOptions);
}
login(token) {
this._setupShoukakuEvents();
this._setupClientEvents();
return super.login(token);
}
_setupShoukakuEvents() {
this.shoukaku.on('ready', (name) => console.log(`Lavalink ${name}: Ready!`));
this.shoukaku.on('error', (name, error) => console.error(`Lavalink ${name}: Error Caught,`, error));
this.shoukaku.on('close', (name, code, reason) => console.warn(`Lavalink ${name}: Closed, Code ${code}, Reason ${reason || 'No reason'}`));
this.shoukaku.on('disconnected', (name, reason) => console.warn(`Lavalink ${name}: Disconnected, Reason ${reason || 'No reason'}`));
}
_setupClientEvents() {
this.on('message', async (msg) => {
if (msg.author.bot || !msg.guild) return;
if (!msg.content.startsWith('$play')) return;
if (this.shoukaku.getPlayer(msg.guild.id)) return;
const args = msg.content.split(' ');
if (!args[1]) return;
const node = this.shoukaku.getNode();
let data = await node.rest.resolve(args[1]);
if (!data) return;
const player = await node.joinVoiceChannel({
guildID: msg.guild.id,
voiceChannelID: msg.member.voice.channelID
});
player.on('error', (error) => {
console.error(error);
player.disconnect();
});
for (const event of ['end', 'closed', 'nodeDisconnect']) player.on(event, () => player.disconnect());
data = data.tracks.shift();
await player.playTrack(data);
await msg.channel.send("Now Playing: " + data.info.title);
});
this.on('ready', () => console.log('Bot is now ready'));
}
}
new ExampleBot()
.login('token')
.catch(console.error);
Made with ❤ by @Sāya#0113