A decentralized music tracking and discovery platform built on AT Protocol 馃幍
at feat/pgpull 49 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); 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 let status = response.status(); 38 tracing::info!(did = %did, artist = %track.artist, track = %track.title, status = %status, "Scrobble response"); 39 if !status.is_success() { 40 let response_text = response.text().await?; 41 tracing::error!(did = %did, response = %response_text, "Failed to scrobble track"); 42 return Err(Error::msg(format!( 43 "Failed to scrobble track: {}", 44 response_text 45 ))); 46 } 47 48 Ok(()) 49}