A decentralized music tracking and discovery platform built on AT Protocol 馃幍
at feat/pgpull 47 lines 1.5 kB view raw
1use anyhow::Error; 2use reqwest::Client; 3 4use crate::{auth::generate_token, cache::Cache, types::Track}; 5 6const ROCKSKY_API: &str = "https://api.rocksky.app"; 7 8pub async fn scrobble(cache: &Cache, did: &str, track: Track, timestamp: u64) -> Result<(), Error> { 9 let key = format!( 10 "{} - {}", 11 track.artist.to_lowercase(), 12 track.title.to_lowercase() 13 ); 14 15 // Check if the track is already in the cache, if not add it 16 if !cache.exists(&key)? { 17 let value = serde_json::to_string(&track)?; 18 let ttl = 15 * 60; // 15 minutes 19 cache.setex(&key, &value, ttl)?; 20 } 21 22 let mut track = track; 23 track.timestamp = Some(timestamp / 1000 as u64); 24 25 let token = generate_token(did)?; 26 let client = Client::new(); 27 28 tracing::info!(did = %did, track = ?track, "Scrobbling track"); 29 30 let response = client 31 .post(&format!("{}/now-playing", ROCKSKY_API)) 32 .bearer_auth(token) 33 .json(&track) 34 .send() 35 .await?; 36 37 if !response.status().is_success() { 38 tracing::error!(did = %did, artist = %track.artist, track = %track.title, status = %response.status(), "Failed to scrobble track"); 39 let text = response.text().await?; 40 tracing::error!(did = %did, response = %text, "Response"); 41 return Err(Error::msg(format!("Failed to scrobble track: {}", text))); 42 } 43 44 tracing::info!(did = %did, artist = %track.artist, track = %track.title, "Scrobbled track"); 45 46 Ok(()) 47}