discord-music-bot/src/lavalink_handler.rs
2025-04-20 00:49:17 +08:00

85 lines
3.3 KiB
Rust

// src/lavalink_handler.rs
use serenity::http::Http; // Import Http for sending messages
use lavalink_rs::gateway::{NodeEvent, LavalinkEventHandler as LavalinkEventHandlerRs};
use tracing::{error, info, instrument};
use async_trait::async_trait; // Needed to implement async trait methods
use std::sync::Arc; // Needed for Arc<Http>
// --- lavalink-rs Event Handler ---
// This handler receives events directly from the connected Lavalink server.
// It allows reacting to playback events like track start/end.
pub struct MyLavalinkEventHandlerRs {
pub http: Arc<Http>, // Hold the Http client to send messages to Discord
// Add state if needed, e.g., channel IDs for announcements per guild.
}
#[async_trait]
impl LavalinkEventHandlerRs for MyLavalinkEventHandlerRs {
// The main handler function for all Lavalink NodeEvents.
#[instrument(skip(self))] // Adds tracing to the handler
async fn handle(&self, event: NodeEvent) {
// You can uncomment this for verbose logging of all events:
// info!("Received LavaLink event: {:?}", event);
match event {
// Handle specific event types
NodeEvent::TrackStart { guild_id, track, .. } => {
info!(
"Track started on guild {}: {}",
guild_id,
track.info.title
);
// Example: send a message announcing the track.
// This requires knowing which channel to send it to, often
// stored per guild in the BotState's announcement_channels.
// Accessing BotState would require passing it here or using a global static.
// let channel_id = { /* logic to get channel_id from guild_id using self.http or shared state */ };
// if let Some(channel_id) = channel_id {
// if let Err(e) = ChannelId(channel_id).say(&self.http,
// format!("Now playing: **{}** by **{}**", track.info.title, track.info.author)
// ).await {
// error!("Failed to send track start message: {}", e);
// }
// }
}
NodeEvent::TrackEnd { guild_id, track, reason, .. } => {
info!(
"Track ended on guild {}: {}, reason: {:?}",
guild_id,
track.info.title,
reason
);
// Logic for track end, e.g., cleaning up state if not using Lavalink queues
}
NodeEvent::TrackException { guild_id, track, error, .. } => {
error!(
"Track exception on guild {}: {}, error: {}",
guild_id,
track.info.title,
error
);
// Notify the channel about the exception
}
NodeEvent::TrackStuck { guild_id, track, threshold_ms, .. } => {
error!(
"Track stuck on guild {}: {}, threshold: {}ms",
guild_id,
track.info.title,
threshold_ms
);
// Notify the channel about the stuck track
}
NodeEvent::WebSocketOpen { node, .. } => {
info!("Lavalink WebSocket opened: {}", node);
}
NodeEvent::WebSocketClosed { node, code, reason, .. } => {
error!("Lavalink WebSocket closed: {}, Code: {:?}, Reason: {}", node, code, reason);
}
// Ignore these common events to avoid log spam
NodeEvent::Ready { .. } | NodeEvent::Stats { .. } => { /* Ignore */ }
NodeEvent::PlayerUpdate { .. } => { /* Ignore */ }
}
}
}