use crate::SpotifyURL::Track; use aspotify::{Client, ClientCredentials}; use std::time::Duration; use teloxide::prelude::*; enum SpotifyURL { Track(String), } struct TrackInfo { name: String, artist: Vec, duration: Duration, } fn get_spotify_entry(url: &str) -> Option { if url.contains("https://open.spotify.com/track/") { let track_id = url.rsplit('/').next().and_then(|x| x.split('?').next()); return match track_id { Some(id) => Some(SpotifyURL::Track(id.to_string())), None => None, }; } return None; } async fn get_spotify_track(spotify: Box, id: &String) -> Option { match spotify.tracks().get_track(id.as_str(), None).await { Ok(track) => Some(TrackInfo { name: track.data.name, artist: track.data.artists.iter().map(|x| x.name.clone()).collect(), duration: track.data.duration, }), Err(_e) => None, } } #[tokio::main] async fn main() { teloxide::enable_logging!(); log::info!("Starting Songlify..."); let bot = Bot::from_env().auto_send(); teloxide::repl(bot, |message| async move { let text = message.update.text().and_then(get_spotify_entry); match text { Some(spotify) => { let spotify_creds = ClientCredentials::from_env().expect("CLIENT_ID and CLIENT_SECRET not found."); let spotify_client = Box::new(Client::new(spotify_creds)); match spotify { Track(id) => { log::debug!("Parsing spotify song: {}", id); let track_info = get_spotify_track(spotify_client, &id).await; match track_info { Some(info) => { let reply = format!( "Track information:\n\ 🎵 Track name: {}\n\ 🧑‍🎤 Artist(s): {}\n\ ⏳ Duration: {} second(s)", info.name, info.artist.join(", "), info.duration.as_secs() ); Some(message.reply_to(reply).await?) } None => None, } } } } None => None, }; respond(()) }) .await; log::info!("Exiting..."); }