Manager Events
The RyanlinkManager emits events throughout the lifecycle of nodes and players. Listen on the manager instance directly.
Node Events
Section titled “Node Events”| Event | Signature | Description |
|---|---|---|
nodeConnect | (node) | Node WebSocket connected. |
nodeDisconnect | (node, reason) | Node WebSocket disconnected. reason.code, reason.reason. |
nodeError | (node, error) | Node encountered an error. |
nodeReady | (node, payload) | Node session ready. payload.resumed, payload.sessionId. |
nodeRaw | (node, payload) | Every raw WebSocket payload from the node. |
Track Events
Section titled “Track Events”| Event | Signature | Description |
|---|---|---|
trackStart | (player, track, payload) | Track begins playing. |
trackEnd | (player, track, payload) | Track finishes. payload.reason: finished, replaced, stopped, loadFailed, cleanup. |
trackStuck | (player, track, payload) | Track stuck for payload.thresholdMs ms. |
trackError | (player, track, payload) | Playback error or unresolved track failure. payload.exception contains severity and cause. |
Queue Events
Section titled “Queue Events”| Event | Signature | Description |
|---|---|---|
queueEnd | (player) | Queue exhausted — no more tracks. |
Player Lifecycle Events
Section titled “Player Lifecycle Events”| Event | Signature | Description |
|---|---|---|
playerCreate | (player) | A new player was created. |
playerDestroy | (player, reason?) | Player was destroyed. |
playerMove | (player, oldChannelId, newChannelId) | Bot moved to a different voice channel. |
playerDisconnect | (player, channelId) | Bot disconnected from voice (when destroyPlayer: false and autoReconnect: false). |
playerSocketClosed | (player, payload) | Discord voice WebSocket closed. payload.code, payload.reason. |
Player State Events
Section titled “Player State Events”| Event | Signature | Description |
|---|---|---|
playerUpdate | (player, oldJson, newJson) | Node sent a position/ping update, or player.syncState() was called. |
SponsorBlock Events Requires sponsorblock-plugin
Section titled “SponsorBlock Events ”| Event | Signature | Description |
|---|---|---|
sponsorBlockSegmentsLoaded | (player, track, payload) | Segments loaded for the current track. |
sponsorBlockSegmentSkipped | (player, track, payload) | A segment was skipped. payload.segment.category. |
sponsorBlockChaptersLoaded | (player, track, payload) | YouTube chapters loaded. |
sponsorBlockChapterStarted | (player, track, payload) | A new chapter started. |
Lyrics Events Requires lavalyrics-plugin or lavasrc-plugin
Section titled “Lyrics Events ”| Event | Signature | Description |
|---|---|---|
lyricsFound | (player, track, payload) | Lyrics found for the current track. |
lyricsNotFound | (player, track, payload) | No lyrics found. |
lyricsLine | (player, track, payload) | Real-time lyrics line event. payload.line, payload.lineIndex, payload.skipped. |
Debug Event
Section titled “Debug Event”| Event | Signature | Description |
|---|---|---|
debug | (eventKey, eventData) | Internal debug events. Only emitted when advancedOptions.enableDebugEvents: true. eventData.state: 'log' | 'warn' | 'error'. |
Usage Example
Section titled “Usage Example”manager.on('trackStart', (player, track, payload) => { console.log(`[${player.guildId}] Now playing: ${track.info.title} by ${track.info.author}`);});
manager.on('trackEnd', (player, track, payload) => { console.log(`[${player.guildId}] Ended (${payload.reason}): ${track.info.title}`);});
manager.on('trackError', (player, track, payload) => { console.error(`[${player.guildId}] Error: ${payload?.exception?.message}`);});
manager.on('queueEnd', (player) => { console.log(`[${player.guildId}] Queue empty`);});
manager.on('playerCreate', (player) => { console.log(`[${player.guildId}] Player created`);});
manager.on('playerDestroy', (player, reason) => { console.log(`[${player.guildId}] Player destroyed: ${reason}`);});
manager.on('playerMove', (player, oldChannel, newChannel) => { console.log(`[${player.guildId}] Moved: ${oldChannel} → ${newChannel}`);});
manager.on('playerSocketClosed', (player, payload) => { console.warn(`[${player.guildId}] WS closed: code=${payload.code} reason=${payload.reason}`);});
manager.on('nodeConnect', (node) => { console.log(`[Node] ${node.id} connected`);});
manager.on('nodeDisconnect', (node, reason) => { console.warn(`[Node] ${node.id} disconnected: ${reason.reason} (${reason.code})`);});
manager.on('nodeReady', (node, payload) => { console.log(`[Node] ${node.id} ready — session: ${payload.sessionId}, resumed: ${payload.resumed}`);});
manager.on('nodeError', (node, error) => { console.error(`[Node] ${node.id} error: ${error.message}`);});
manager.on('sponsorBlockSegmentSkipped', (player, track, payload) => { console.log(`[SponsorBlock] Skipped: ${payload.segment.category}`);});
manager.on('lyricsLine', (player, track, payload) => { console.log(`[Lyrics] ${payload.line.line}`);});
manager.on('debug', (eventKey, eventData) => { if (eventData.state === 'error') console.error(`[Debug] ${eventKey}: ${eventData.message}`);});