A decentralized music tracking and discovery platform built on AT Protocol 馃幍
rocksky.app
spotify
atproto
lastfm
musicbrainz
scrobbling
listenbrainz
1use std::env;
2
3use anyhow::Error;
4use reqwest::Client;
5
6use crate::types::{self, token::AccessToken};
7
8pub async fn refresh_token(token: &str) -> Result<AccessToken, Error> {
9 if env::var("SPOTIFY_CLIENT_ID").is_err() || env::var("SPOTIFY_CLIENT_SECRET").is_err() {
10 panic!("Please set SPOTIFY_CLIENT_ID and SPOTIFY_CLIENT_SECRET environment variables");
11 }
12
13 let client_id = env::var("SPOTIFY_CLIENT_ID")?;
14 let client_secret = env::var("SPOTIFY_CLIENT_SECRET")?;
15
16 let client = Client::new();
17
18 let response = client
19 .post("https://accounts.spotify.com/api/token")
20 .basic_auth(&client_id, Some(client_secret))
21 .form(&[
22 ("grant_type", "refresh_token"),
23 ("refresh_token", token),
24 ("client_id", &client_id),
25 ])
26 .send()
27 .await?;
28 let token = response.json::<AccessToken>().await?;
29 Ok(token)
30}
31
32pub async fn get_user_playlists(token: String) -> Result<Vec<types::playlist::Playlist>, Error> {
33 let token = refresh_token(&token).await?;
34 let client = Client::new();
35 let response = client
36 .get("https://api.spotify.com/v1/me/playlists")
37 .header("Authorization", format!("Bearer {}", token.access_token))
38 .send()
39 .await?;
40 let playlists = response.json::<types::playlist::SpotifyResponse>().await?;
41 let mut all_playlists = vec![];
42
43 for playlist in playlists.items {
44 all_playlists.push(get_playlist(&playlist.id, &token.access_token).await?);
45 // wait for 1 second to avoid rate limiting
46 tokio::time::sleep(tokio::time::Duration::from_secs(1)).await;
47 }
48
49 Ok(all_playlists)
50}
51
52pub async fn get_playlist(id: &str, token: &str) -> Result<types::playlist::Playlist, Error> {
53 let client = Client::new();
54 let response = client
55 .get(format!("https://api.spotify.com/v1/playlists/{}", id))
56 .header("Authorization", format!("Bearer {}", token))
57 .send()
58 .await?;
59
60 let playlist = response.json::<types::playlist::Playlist>().await?;
61 Ok(playlist)
62}