Skip to content

Manager Events

The RyanlinkManager emits events throughout the lifecycle of nodes and players. Listen on the manager instance directly.

| 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. |

| 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. |

| Event | Signature | Description | | :--- | :--- | :--- | | queueEnd | (player) | Queue exhausted — no more tracks. |

| 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. |

| 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. |

| Event | Signature | Description | | :--- | :--- | :--- | | debug | (eventKey, eventData) | Internal debug events. Only emitted when advancedOptions.enableDebugEvents: true. eventData.state: 'log' \| 'warn' \| 'error'. |


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}`);
});