diff --git a/SpotifyESP32.cpp b/SpotifyESP32.cpp index 4c741d3..67817ed 100644 --- a/SpotifyESP32.cpp +++ b/SpotifyESP32.cpp @@ -10,6 +10,13 @@ namespace Spotify_types{ String TYPE_ARTIST = "artist"; String TYPE_TRACK = "track"; String TYPE_PLAYLIST = "playlist"; + String GROUP_ALBUM = "album"; + String GROUP_SINGLE = "single"; + String GROUP_APPEARS_ON = "appears_on"; + String GROUP_COMPILATION = "compilation"; + String TIME_RANGE_SHORT = "short_term"; + String TIME_RANGE_MEDIUM = "medium_term"; + String TIME_RANGE_LONG = "long_term"; } @@ -57,7 +64,7 @@ response Spotify::RestApiGet(char rest_url[_size_of_possibly_large_char]){ return response_obj; } -response Spotify::RestApiPut(char rest_url[100], String payload){ +response Spotify::RestApiPut(char rest_url[_size_of_possibly_large_char], String payload){ response response_obj; init_response(&response_obj); @@ -156,7 +163,6 @@ response Spotify::RestApiPost(char rest_url[100], String payload){ return response_obj; } -//Untested response Spotify::RestApiDelete(char rest_url[100], String payload){ response response_obj; init_response(&response_obj); @@ -206,6 +212,7 @@ response Spotify::RestApiDelete(char rest_url[100], String payload){ return response_obj; } + //Player response Spotify::currently_playing(){ char url[] = "https://api.spotify.com/v1/me/player/currently-playing"; @@ -246,7 +253,6 @@ response Spotify::previous(){ char url[] = "https://api.spotify.com/v1/me/player/previous"; return RestApiPost(url); - } response Spotify::available_devices(){ char url[] = "https://api.spotify.com/v1/me/player/devices"; @@ -257,10 +263,7 @@ response Spotify::recently_played_tracks(int limit){ String url = "https://api.spotify.com/v1/me/player/recently-played"; url += "?limit="+String(limit); - char url_char_array[100]; - url.toCharArray(url_char_array, sizeof(url_char_array)); - - return RestApiGet(url_char_array); + return RestApiGet(const_cast(url.c_str())); } response Spotify::get_queue(){ char url[] = "https://api.spotify.com/v1/me/player/queue"; @@ -269,7 +272,7 @@ response Spotify::get_queue(){ } response Spotify::transfer_playback(String device_id){ char url[] = "https://api.spotify.com/v1/me/player"; - String payload= "{\"device_ids\":[\"" + device_id + "\"]}"; + String payload = "{\"device_ids\":[\"" + device_id + "\"]}"; return RestApiPut(url, payload); } @@ -277,28 +280,19 @@ response Spotify::seek_to_position(int time_ms){ String url = "https://api.spotify.com/v1/me/player/seek"; url += "?position_ms="+String(time_ms); - char url_char_array[100]; - url.toCharArray(url_char_array, sizeof(url_char_array)); - - return RestApiPut(url_char_array); + return RestApiPut(const_cast(url.c_str())); } response Spotify::repeat_mode(String mode){ String url = "https://api.spotify.com/v1/me/player/repeat"; url += "?state="+mode; - char url_char_array[100]; - url.toCharArray(url_char_array, sizeof(url_char_array)); - - return RestApiPut(url_char_array); + return RestApiPut(const_cast(url.c_str())); } response Spotify::set_volume(int value){ String url = "https://api.spotify.com/v1/me/player/volume"; url += "?volume_percent="+String(value); - char url_char_array[100]; - url.toCharArray(url_char_array, sizeof(url_char_array)); - - return RestApiPut(url_char_array); + return RestApiPut(const_cast(url.c_str())); } response Spotify::shuffle(bool mode){ String state; @@ -311,10 +305,7 @@ response Spotify::shuffle(bool mode){ String url = "https://api.spotify.com/v1/me/player/shuffle"; url += "?state=" + state; - char url_char_array[100]; - url.toCharArray(url_char_array, sizeof(url_char_array)); - - return RestApiPut(url_char_array); + return RestApiPut(const_cast(url.c_str())); } response Spotify::add_to_queue(String context_uri){ response response_obj; @@ -322,60 +313,44 @@ response Spotify::add_to_queue(String context_uri){ String url = "https://api.spotify.com/v1/me/player/queue"; url += "?uri="+context_uri; - char url_char_array[100]; - url.toCharArray(url_char_array, sizeof(url_char_array)); - - return RestApiPost(url_char_array); + return RestApiPost(const_cast(url.c_str())); } + //Albums response Spotify::get_album(String id){ - String url = "https://api.spotify.com/v1/albums"; - url += "/" + id; + String url = "https://api.spotify.com/v1/albums/"; + url += id; - char url_char_array[100]; - url.toCharArray(url_char_array, sizeof(url_char_array)); - - return RestApiGet(url_char_array); + return RestApiGet(const_cast(url.c_str())); } response Spotify::get_albums(String ids){ String url = "https://api.spotify.com/v1/albums"; url += "?ids=" + ids; - char url_char_array[_size_of_possibly_large_char]; - url.toCharArray(url_char_array, sizeof(url_char_array)); - - return RestApiGet(url_char_array); + return RestApiGet(const_cast(url.c_str())); } response Spotify::get_album_tracks(String id, int limit, int offset){ String url = "https://api.spotify.com/v1/albums/"; url += id + "/tracks?limit=" + String(limit) + "&offset=" + String(offset); - char url_char_array[100]; - url.toCharArray(url_char_array, sizeof(url_char_array)); - - return RestApiGet(url_char_array); - + return RestApiGet(const_cast(url.c_str())); } response Spotify::get_users_saved_albums(int limit, int offset){ String url = "https://api.spotify.com/v1/me/albums"; url += "?limit=" + String(limit) + "&offset=" + String(offset); - char url_char_array[100]; - url.toCharArray(url_char_array, sizeof(url_char_array)); - - return RestApiGet(url_char_array); - + return RestApiGet(const_cast(url.c_str())); } -response Spotify::save_albums_for_current_user(String ids){ +response Spotify::save_albums_for_current_user(String ids_json){ char url[] = "https://api.spotify.com/v1/me/albums"; - return RestApiPut(url, ids); + return RestApiPut(url, ids_json); } -response Spotify::remove_users_saved_albums(String ids){ +response Spotify::remove_users_saved_albums(String ids_json){ char url[] = "https://api.spotify.com/v1/me/albums"; - return RestApiDelete(url, ids); + return RestApiDelete(url, ids_json); } response Spotify::check_useres_saved_albums(String ids){ String url = "https://api.spotify.com/v1/me/albums/contains"; @@ -390,11 +365,425 @@ response Spotify::get_new_releases(String country, int limit, int offset){ String url = "https://api.spotify.com/v1/browse/new-releases"; url += "?country=" + country + "&limit=" + String(limit) + "&offset=" + String(offset); - char url_char_array[100]; + return RestApiGet(const_cast(url.c_str())); +} + +//Artists +response Spotify::get_artist(String id){ + String url = "https://api.spotify.com/v1/artists/"; + url += id; + + return RestApiGet(const_cast(url.c_str())); +} +response Spotify::get_several_artists(String ids){ + String url = "https://api.spotify.com/v1/artists"; + url += "?ids=" + ids; + + return RestApiGet(const_cast(url.c_str())); +} +response Spotify::get_artist_albums(String id, String include_groups, int limit, int offset){ + String url = "https://api.spotify.com/v1/artists/"; + url += id +"/albums?include_groups="+ include_groups +"&limit=" + limit +"&offset=" + offset; + + return RestApiGet(const_cast(url.c_str())); +} +response Spotify::get_artist_top_tracks(String id){ + String url = "https://api.spotify.com/v1/artists/"; + url += id + "/top-tracks"; + + return RestApiGet(const_cast(url.c_str())); + +} +response Spotify::get_artist_related_artist(String id){ + String url = "https://api.spotify.com/v1/artists/"; + url += id + "/related-artists"; + + return RestApiGet(const_cast(url.c_str())); +} + +//Audiobooks +response Spotify::get_audiobook(String id){ + String url = "https://api.spotify.com/v1/audiobooks/"; + url += id; + + return RestApiGet(const_cast(url.c_str())); + +} +response Spotify::get_several_audiobooks(String ids){ + String url = "https://api.spotify.com/v1/audiobooks"; + url += "?ids=" + ids; + + return RestApiGet(const_cast(url.c_str())); +} +response Spotify::get_audiobook_chapters(String id, int limit, int offset){ + String url = "https://api.spotify.com/v1/audiobooks/"; + url += id +"/chapters?limit=" + limit +"&offset=" + offset; + + return RestApiGet(const_cast(url.c_str())); +} +response Spotify::get_users_audiobooks(int limit, int offset){ + String url = "https://api.spotify.com/v1/me/audiobooks"; + url += "?limit=" + String(limit) + "&offset=" + String(offset); + + return RestApiGet(const_cast(url.c_str())); +} +response Spotify::save_audiobooks_for_current_user(String ids){ + String url = "https://api.spotify.com/v1/me/audiobooks"; + url += "?ids=" + ids; + + return RestApiPut(const_cast(url.c_str())); +} +response Spotify::remove_audiobooks_for_current_user(String ids){ + String url = "https://api.spotify.com/v1/me/audiobooks"; + url += "?ids=" + ids; + + return RestApiDelete(const_cast(url.c_str())); +} +response Spotify::check_users_saved_audiobooks(String ids){ + String url = "https://api.spotify.com/v1/me/audiobooks/contains"; + url += "?ids=" + ids; + + return RestApiGet(const_cast(url.c_str())); +} + +//Categories +response Spotify::get_several_browse_categories(String country, String locale, int limit, int offset){ + String url = "https://api.spotify.com/v1/browse/categories"; + url += "?country=" + country + "&locale=" + locale + "&limit=" + String(limit) + "&offset=" + String(offset); + + return RestApiGet(const_cast(url.c_str())); +} +response Spotify::get_single_browse_category(String category_id, String country, String locale){ + String url = "https://api.spotify.com/v1/browse/categories/"; + url += category_id+ "?country=" + country + "&locale=" + locale; + + return RestApiGet(const_cast(url.c_str())); +} + +//Chapters +response Spotify::get_chapter(String id){ + String url = "https://api.spotify.com/v1/chapters/"; + url += id; + + return RestApiGet(const_cast(url.c_str())); + +} +response Spotify::get_several_chapters(String ids){ + String url = "https://api.spotify.com/v1/chapters"; + url += +"?ids=" + ids; + + char url_char_array[_size_of_possibly_large_char]; url.toCharArray(url_char_array, sizeof(url_char_array)); return RestApiGet(url_char_array); } + +//Episodes +response Spotify::get_episode(String id){ + String url = "https://api.spotify.com/v1/episodes/"; + url += id; + + return RestApiGet(const_cast(url.c_str())); +} +response Spotify::get_several_episodes(String ids){ + String url = "https://api.spotify.com/v1/episodes"; + url += "?ids=" + ids; + + return RestApiGet(const_cast(url.c_str())); +} +response Spotify::get_users_saved_episodes(int limit, int offset){ + String url = "https://api.spotify.com/v1/me/episodes"; + url += "?limit=" + String(limit) + "&offset=" + String(offset); + + return RestApiGet(const_cast(url.c_str())); +} +response Spotify::save_episodes_for_current_user(String ids_json){ + char url[] = "https://api.spotify.com/v1/me/episodes"; + + return RestApiPut(url, ids_json); +} +response Spotify::remove_episodes_for_current_user(String ids_json){ + char url[] = "https://api.spotify.com/v1/me/episodes"; + + return RestApiDelete(url, ids_json); +} +response Spotify::check_users_saved_episodes(String ids){ + String url = "https://api.spotify.com/v1/me/episodes/contains"; + url += "?ids=" + ids; + + return RestApiGet(const_cast(url.c_str())); +} + +//Genres +response Spotify::get_available_genre_seeds(){ + char url[] = "https://api.spotify.com/v1/recommendations/available-genre-seeds"; + + return RestApiGet(url); +} + +//Markets +response Spotify::get_available_markets(){ + char url[] = "https://api.spotify.com/v1/markets"; + + return RestApiGet(url); +} + +//Playlist +response Spotify::get_playlist(String playlist_id, String fields) { + String url = "https://api.spotify.com/v1/playlists/"; + url += playlist_id + "?fields=" +fields; + + return RestApiGet(const_cast(url.c_str())); +} +response Spotify::change_playlist_details(String playlist_id, String name, bool is_public, bool is_collaborative, String description) { + String url = "https://api.spotify.com/v1/playlists/"; + url += playlist_id; + DynamicJsonDocument doc(400); + + doc["name"] = name; + doc["public"] = is_public; + doc["collaborative"] = is_collaborative; + doc["description"] = description; + + String payload; + serializeJson(doc, payload); + + return RestApiPut(const_cast(url.c_str()), payload); +} +response Spotify::get_playlist_items(String playlist_id, String fields, int limit, int offset) { + String url = "https://api.spotify.com/v1/playlists/"; + url += playlist_id + "/tracks?fields=" + fields + "&limit=" + String(limit) + "&offset=" + String(offset); + + return RestApiGet(const_cast(url.c_str())); +} +response Spotify::update_playlist_items(String playlist_id, String uris, int range_start, int insert_before, int range_length) { + String url = "https://api.spotify.com/v1/playlists/"; + url += playlist_id + "/tracks"; + String payload = "{\"uris\":\"" + uris + "\",\"range_start\":" + String(range_start) + ",\"insert_before\":" + String(insert_before) + ",\"range_length\":\"" + String(range_length) + "\"}"; + + return RestApiPut(const_cast(url.c_str()), payload); +} +response Spotify::add_items_to_playlist(String playlist_id, String uris, int position) { + String url = "https://api.spotify.com/v1/playlists/"; + url += playlist_id + "/tracks"; + String payload = "{\"uris\":\"" + uris + "\",\"position\":" + String(position)+ "\"}"; + + return RestApiPost(const_cast(url.c_str()), payload); +} +response Spotify::remove_playlist_items(String playlist_id, String uris_array) { //Arrays + String url = "https://api.spotify.com/v1/playlists/"; + url += playlist_id + "/tracks"; + + return RestApiDelete(const_cast(url.c_str()), uris_array); +} +response Spotify::get_current_users_playlists(int limit, int offset) { + String url = "https://api.spotify.com/v1/me/playlists"; + url += "?limit=" + String(limit) + "&offset=" + String(offset); + + return RestApiGet(const_cast(url.c_str())); +} +response Spotify::get_user_playlists(String user_id, int limit, int offset) { + String url = "https://api.spotify.com/v1/users/"; + url += user_id + "/playlists?limit=" + String(limit) + "&offset=" +String(offset); + + return RestApiGet(const_cast(url.c_str())); +} +response Spotify::create_playlist(String user_id, String name, bool is_public, bool is_collaborative, String description) { + String url = "https://api.spotify.com/v1/users/"; + url += user_id + "/playlists"; + String payload = "{\"name\":\"" + name + "\",\"public\":" + (is_public ? "true" : "false") + ",\"collaborative\":" + (is_collaborative ? "true" : "false")+"\",\"public\":"+description +"\"}"; + return RestApiPost(const_cast(url.c_str()),payload); +} +response Spotify::get_featured_playlists(String country, String locale, String timestamp, int limit, int offset) { + String url = "https://api.spotify.com/v1/browse/featured-playlists"; + url += "?country" + country + "&locale=" + locale + "×tamp=" + timestamp + "&limit=" + String(limit) + "&offset=" + String(offset); + + return RestApiGet(const_cast(url.c_str())); +} +response Spotify::get_category_playlists(String category_id, String country, int limit, int offset) { + String url = "https://api.spotify.com/v1/browse/categories/"; + url += category_id + "/playlists?country" + country + "&limit=" + String(limit) + "&offset=" + String(offset); + + return RestApiGet(const_cast(url.c_str())); +} +response Spotify::get_playlist_cover_image(String playlist_id) { + String url = "https://api.spotify.com/v1/playlists/"; + url += playlist_id + "/images"; + + return RestApiGet(const_cast(url.c_str())); +} +response Spotify::add_custom_playlist_cover_image(String playlist_id, String data) { + String url = "https://api.spotify.com/v1/playlists/"; + url += playlist_id + "/images"; + + return RestApiPut(const_cast(url.c_str()),data); +} + +//Search +response Spotify::search(String q, String type, int limit, int offset){ + String url = "https://api.spotify.com/v1/search"; + url += "?q=" + q + "&type=" + type + "&limit=" + String(limit) + "&offset=" + String(offset); + return RestApiGet(const_cast(url.c_str())); +} + +//Shows +response Spotify::get_show(String id) { + String url = "https://api.spotify.com/v1/shows/"; + url += id; + + return RestApiGet(const_cast(url.c_str())); +} +response Spotify::get_several_shows(String ids) { + String url = "https://api.spotify.com/v1/shows"; + url += "?ids=" + ids; + + return RestApiGet(const_cast(url.c_str())); +} +response Spotify::get_show_episodes(String id, int limit, int offset) { + String url = "https://api.spotify.com/v1/shows/"; + url += id + "/episodes?limit=" + String(limit) + "&offset=" + String(offset); + + return RestApiGet(const_cast(url.c_str())); +} +response Spotify::get_users_saved_shows(int limit, int offset) { + String url = "https://api.spotify.com/v1/me/shows"; + url += "?limit=" + String(limit) + "&offset=" + String(offset); + + return RestApiGet(const_cast(url.c_str())); +} +response Spotify::save_shows_for_current_user(String ids) { + String url = "https://api.spotify.com/v1/me/shows"; + url += "?ids=" + ids; + + return RestApiPut(const_cast(url.c_str())); +} +response Spotify::remove_shows_for_current_user(String ids) { + String url = "https://api.spotify.com/v1/me/shows"; + url += "?ids=" + ids; + + return RestApiDelete(const_cast(url.c_str())); +} +response Spotify::check_users_saved_shows(String ids) { + String url = "https://api.spotify.com/v1/me/shows/contains"; + url += "?ids=" + ids; + + return RestApiGet(const_cast(url.c_str())); +} + +//Tracks +response Spotify::get_track(String track_id) { + String url = "https://api.spotify.com/v1/tracks/"; + url += track_id; + + return RestApiGet(const_cast(url.c_str())); +} +response Spotify::get_several_tracks(String track_ids) { + String url = "https://api.spotify.com/v1/tracks"; + url += "?ids=" + track_ids; + + return RestApiGet(const_cast(url.c_str())); +} +response Spotify::get_user_saved_tracks(int limit, int offset) { + String url = "https://api.spotify.com/v1/me/tracks"; + url += "?limit=" + String(limit) + "&offset=" + String(offset); + + return RestApiGet(const_cast(url.c_str())); +} +response Spotify::save_tracks_for_current_user(String track_ids_json) { + char url[] = "https://api.spotify.com/v1/me/tracks"; + + return RestApiPut(url, track_ids_json); +} +response Spotify::remove_user_saved_tracks(String track_ids_json) { + char url[] = "https://api.spotify.com/v1/me/tracks"; + + return RestApiDelete(url, track_ids_json); +} +response Spotify::check_user_saved_tracks(String track_ids) { + String url = "https://api.spotify.com/v1/me/tracks/contains"; + url += "?ids=" + track_ids; + + return RestApiGet(const_cast(url.c_str())); +} +response Spotify::get_tracks_audio_features(String track_ids) { + String url = "https://api.spotify.com/v1/audio-features"; + url += "?ids=" + track_ids; + + return RestApiGet(const_cast(url.c_str())); +} +response Spotify::get_track_audio_features(String track_id) { + String url = "https://api.spotify.com/v1/audio-features/"; + url += track_id; + + return RestApiGet(const_cast(url.c_str())); +} +response Spotify::get_track_audio_analysis(String track_id) { + String url = "https://api.spotify.com/v1/audio-analysis/"; + url += track_id; + + return RestApiGet(const_cast(url.c_str())); +} +//Users +response Spotify::get_current_user_profile() { + char url[] = "https://api.spotify.com/v1/me"; + + return RestApiGet(url); +} +response Spotify::get_user_top_items(String type, String time_range, int limit, int offset) { + String url = "https://api.spotify.com/v1/me/top/"; + url += type +"?time_range=" + time_range + "&limit=" + String(limit) + "&offset=" + String(offset); + + return RestApiGet(const_cast(url.c_str())); +} +response Spotify::get_user_profile(String user_id) { + String url = "https://api.spotify.com/v1/users/"; + url += user_id; + + return RestApiGet(const_cast(url.c_str())); +} +response Spotify::follow_playlist(String playlist_id, bool is_public) { + String url = "https://api.spotify.com/v1/playlists/"; + url += playlist_id + "/followers"; + String payload = is_public ? "true" : "false"; + + return RestApiPut(const_cast(url.c_str()),payload); +} +response Spotify::unfollow_playlist(String playlist_id) { + String url = "https://api.spotify.com/v1/playlists/"; + url += playlist_id + "/followers"; + + return RestApiDelete(const_cast(url.c_str())); +} +response Spotify::get_followed_artists(String type, String after, int limit) { + String url = "https://api.spotify.com/v1/me/following"; + url += "?type=" + type + "&after=" + after + "&limit=" + String(limit); + + return RestApiGet(const_cast(url.c_str())); +} +response Spotify::follow_artists_or_users(String type, String artist_user_ids_json) { + String url = "https://api.spotify.com/v1/me/following"; + url += "?type=" + type; + + return RestApiPut(const_cast(url.c_str()), artist_user_ids_json); +} +response Spotify::unfollow_artists_or_users(String type, String artist_user_ids_json) { + String url = "https://api.spotify.com/v1/me/following"; + url += "?type=" + type; + + return RestApiDelete(const_cast(url.c_str()), artist_user_ids_json); +} +response Spotify::check_if_user_follows_artists_or_users(String type, String artist_user_ids) { + String url = "https://api.spotify.com/v1/me/following/contains"; + url += "?type=" + type + "&ids=" + artist_user_ids; + + return RestApiGet(const_cast(url.c_str())); +} +response Spotify::check_if_users_follow_playlist(String playlist_id, String user_ids) { + String url = "https://api.spotify.com/v1/playlists/"; + url += playlist_id + "followers/contains?ids=" + user_ids; + + return RestApiGet(const_cast(url.c_str())); +} void Spotify::init_response(response* response_obj){ response_obj -> status_code = -1; response_obj -> reply ="If you see this something went wrong"; @@ -507,7 +896,6 @@ String Spotify::convert_id_to_uri(String id, String type){ String uri = "spotify:"+type+":"+id; return uri; } - String Spotify::comma_separated_string_to_json(String list) { DynamicJsonDocument doc(512); String token; @@ -525,3 +913,4 @@ String Spotify::comma_separated_string_to_json(String list) { serializeJson(doc, list_doc); return list_doc; } + diff --git a/SpotifyESP32.h b/SpotifyESP32.h index 5496759..9ea0831 100644 --- a/SpotifyESP32.h +++ b/SpotifyESP32.h @@ -17,12 +17,22 @@ namespace Spotify_types{ extern String TYPE_ARTIST; extern String TYPE_TRACK; extern String TYPE_PLAYLIST; + extern String GROUP_ALBUM; + extern String GROUP_SINGLE; + extern String GROUP_APPEARS_ON; + extern String GROUP_COMPILATION; + extern String TIME_RANGE_SHORT; + extern String TIME_RANGE_MEDIUM; + extern String TIME_RANGE_LONG; }; typedef struct{ int status_code; String reply; } response; +struct recommendations{ + +}; void print_response(response response_obj); class Spotify { @@ -37,7 +47,7 @@ class Spotify { response previous(); response available_devices(); response current_playback_state(); - response recently_played_tracks(int limit); + response recently_played_tracks(int limit = 10); response seek_to_position(int time_ms); response get_queue(); response repeat_mode(String mode); @@ -48,89 +58,104 @@ class Spotify { //Albums response get_album(String id); response get_albums(String ids); - response get_album_tracks(String id, int limit, int offset); - response get_users_saved_albums(int limit, int offset); - response save_albums_for_current_user(String ids); - response remove_users_saved_albums(String ids); + response get_album_tracks(String id, int limit = 10, int offset = 0); + response get_users_saved_albums(int limit = 10, int offset = 0); + response save_albums_for_current_user(String ids_json); + response remove_users_saved_albums(String ids_json); response check_useres_saved_albums(String ids); - response get_new_releases(String country, int limit, int offset); + response get_new_releases(String country, int limit = 10, int offset = 0); //Artists response get_artist(String id); response get_several_artists(String ids); - response get_artist_albums(String id); + response get_artist_albums(String id, String include_groups, int limit = 10, int offset = 0); response get_artist_top_tracks(String id); response get_artist_related_artist(String id); //Audiobooks response get_audiobook(String id); response get_several_audiobooks(String ids); - response get_audiobook_chapters(String id); - response get_users_audiobooks(int limit, int offset); + response get_audiobook_chapters(String id, int limit = 10, int offset = 0); + response get_users_audiobooks(int limit = 10, int offset = 0); response save_audiobooks_for_current_user(String ids); - response remove_audiobooks_for_current_user(String id); + response remove_audiobooks_for_current_user(String ids); response check_users_saved_audiobooks(String ids); //Categories - response get_several_browse_categories(String country, String locale, int limit, int offset); + response get_several_browse_categories(String country, String locale, int limit = 10, int offset = 0); response get_single_browse_category(String category_id, String country, String locale); - //Chapters + //Chapters (Only Available in US, UK, Canada, Ireland, New Zealand and Australia) response get_chapter(String id); response get_several_chapters(String ids); //Episodes response get_episode(String id); response get_several_episodes(String ids); - response get_users_saved_episodes(int limit, int offset); - response save_episodes_for_current_user(String ids); + response get_users_saved_episodes(int limit = 10, int offset = 0); + response save_episodes_for_current_user(String ids_json); response remove_episodes_for_current_user(String id); - response check_users_saved_episodes(String ids); + response check_users_saved_episodes(String ids_json); //Genres response get_available_genre_seeds(); //Markets response get_available_markets(); //Playlists - response get_playlist(String playlist_id, String fields, String additional_type); + response get_playlist(String playlist_id, String fields); response change_playlist_details(String playlist_id, String name, bool is_public, bool is_collaborative, String description); - response get_playlist_items(String playlist_id, String fields, String additional_types, int limit, int offset); - response update_playlist_items(String playlist_id, String uris, int range_start,int insert_before,int range_length, String snapshot_id); + response get_playlist_items(String playlist_id, String fields, int limit = 10, int offset = 0); + response update_playlist_items(String playlist_id, String uris, int range_start = 0, int insert_before = 1, int range_length = 1); response add_items_to_playlist(String playlist_id, String uris, int position); - response remove_playlist_items(String playlist_id, String uris, String snapshot_id); - response get_current_users_playlists(int limit, int offset); - response get_user_playlists(String user_id,int limit, int offset); + response remove_playlist_items(String playlist_id, String uris_array); + response get_current_users_playlists(int limit = 10, int offset = 0); + response get_user_playlists(String user_id,int limit = 10, int offset = 0); response create_playlist(String user_id, String name, bool is_public, bool is_collaborative, String description); - response get_featured_playlists(String country, String locale, String timestamp,int limit, int offset); - response get_category_playlists(String category_id, String country, int limit, int offset); + response get_featured_playlists(String country, String locale, String timestamp,int limit = 10, int offset = 0); + response get_category_playlists(String category_id, String country, int limit = 10, int offset = 0); response get_playlist_cover_image(String playlist_id); response add_custom_playlist_cover_image(String playlist_id, String data); //Search - response search(String q, String type, int limit, int offset); + response search(String q, String type, int limit = 10, int offset = 0); //Shows response get_show(String id); response get_several_shows(String ids); - response get_show_episodes(String id, int limit, int offset); - response get_users_saved_shows(int limit, int offset); + response get_show_episodes(String id, int limit = 10, int offset = 0); + response get_users_saved_shows(int limit = 10, int offset = 0); response save_shows_for_current_user(String ids); - response remove_shows_for_current_user(String id); + response remove_shows_for_current_user(String ids); response check_users_saved_shows(String ids); //Tracks response get_track(String track_id); - response get_several_tracks(); - response get_user_saved_tracks(); - response save_tracks_for_current_user(); - response remove_user_saved_tracks(); - response check_user_saved_tracks(); - response get_tracks_audio_features(); - response get_track_audio_features(); - response get_track_audio_analysis(); - response get_recommendations(); + response get_several_tracks(String track_ids); + response get_user_saved_tracks(int limit = 10, int offset = 0); + response save_tracks_for_current_user(String track_ids_json); + response remove_user_saved_tracks(String track_ids_json); + response check_user_saved_tracks(String track_ids); + response get_tracks_audio_features(String track_ids); + response get_track_audio_features(String track_id); + response get_track_audio_analysis(String track_id); + response get_recommendations(int limit = 10, String seed_artists = "", String seed_genres = "", String seed_tracks = "", + int min_acousticness = -1, int max_acousticness = -1, int target_acousticness = -1, + int min_danceability = -1, int max_danceability = -1, int target_danceability = -1, + int min_duration_ms = -1, int max_duration_ms = -1, int target_duration_ms = -1, + int min_energy = -1, int max_energy = -1, int target_energy = -1, + int min_instrumentalness = -1, int max_instrumentalness = -1, int target_instrumentalness = -1, + int min_key = -1, int max_key = -1, int target_key = -1, + int min_liveness = -1, int max_liveness = -1, int target_liveness = -1, + int min_loudness = -1, int max_loudness = -1, int target_loudness = -1, + int min_mode = -1, int max_mode = -1, int target_mode = -1, + int min_popularity = -1, int max_popularity = -1, int target_popularity = -1, + int min_speechiness = -1, int max_speechiness = -1, int target_speechiness = -1, + int min_tempo = -1, int max_tempo = -1, int target_tempo = -1, + int min_time_signature = -1, int max_time_signature = -1, int target_time_signature = -1, + int min_valence = -1, int max_valence = -1, int target_valence = -1); //Users response get_current_user_profile(); - response get_user_top_items(); - response get_user_profile(); - response follow_playlist(); - response unfollow_playlist(); - response get_followed_artists(); - response follow_artists_or_users(); - response unfollow_artists_or_users(); - response check_if_user_follows_artists_or_users(); - response check_if_users_follow_playlist(); + response get_user_top_items(String type, String time_range = "medium_term", int limit = 10, int offset = 0); + response get_user_profile(String user_id); + response follow_playlist(String playlist_id, bool is_public); + response unfollow_playlist(String playlist_id); + response get_followed_artists(String after, String type = "artist", int limit = 10); + response follow_artists_or_users(String type, String artist_user_ids_json); + response unfollow_artists_or_users(String type, String artist_user_ids_json); + response check_if_user_follows_artists_or_users(String type, String artist_user_ids); + response check_if_users_follow_playlist(String playlist_id, String user_ids); + //Simplified versions of the above String current_track_name(); String current_track_id(); @@ -142,6 +167,7 @@ class Spotify { private: static const int _size_of_possibly_large_char = 600; + char string_to_char(String data, int size); bool get_token(); void init_response(response* response_obj); response RestApiGet(char rest_url[_size_of_possibly_large_char]); diff --git a/Spotify_Esp32_test.ino b/Spotify_Esp32_test.ino index 3057af7..d50f149 100644 --- a/Spotify_Esp32_test.ino +++ b/Spotify_Esp32_test.ino @@ -13,14 +13,42 @@ char* refresh_token="AQAichrGMfjjDHYWIAENJYyWoi_KpzLZ93_HSS30J8zULeuHRPmF9-Wh3aS using namespace Spotify_types; -Spotify sp(refresh_token, redirect_uri, client_id, client_secret, true); +Spotify sp(refresh_token, redirect_uri, client_id, client_secret, false); String song_id = "2NTCi4wGypj56t843jb3Mt"; +String track_id = "2NTCi4wGypj56t843jb3Mt"; +String track_ids = "7ouMYWpwJ422jRcDASZB7P,4VqPOruhp5EdPBeR92t6lQ,2takcwOaAZWiXQijPHIx7B"; + String album_id = "7iLuHJkrb9KHPkMgddYigh"; String album_ids = "7iLuHJkrb9KHPkMgddYigh,4KAtLRVIfB0bKnRY01dveY,2SxoeF005n621Jca66RRdu"; + +String artist_id = "7orlzf5LTqSnCzURkZFebN"; +String artist_ids = "7orlzf5LTqSnCzURkZFebN,0lNJF6sbrXXPubqKkkyK23,3JsMj0DEzyWc0VDlHuy9Bx"; + +String audiobook_id = "18yVqkdbdRvS24c0Ilj2ci"; +String audiobook_ids = "18yVqkdbdRvS24c0Ilj2ci,1HGw3J3NxZO1TP1BTtVhpZ,7iHfbu1YPACw6oZPAFJtqe"; + +String country = "CH"; +String locale = "de_CH"; +String category_id = "dinner"; + +String episode_id = "77o6BIVlYM3msb4MMIL1jH"; +String episode_ids = "77o6BIVlYM3msb4MMIL1jH,0Q86acNRm6V9GYx55SXKwf"; + +String playlist_id = "6lGlX7KRHmy6AuF5NFT0TW"; +String fields = "items(track(name,href,album(name,href)))"; +String uris_array = ""; + +String user_id = "chaerne"; + +String show_id = "5CfCWKI5pZ28U0uOzXkDHe"; +String show_ids = "5CfCWKI5pZ28U0uOzXkDHe,5as3aKmN2k11yfDDDSrvaZ"; + +String artist_user_ids = "2CIMQHirSU0MQqyYHq0eOx,57dN52uHvrHOxijzpIgu3E,1vCWHaC5f2uS3yhpwWbIA6"; + void setup() { Serial.begin(9600); connectToWifi(); - + test_search(); } void loop() { @@ -111,4 +139,198 @@ void test_albums(){ Serial.print("Get Releases: "); print_response(sp.get_new_releases("CH", 1, 0)); +} +void test_artist(){ + Serial.println("Get Artist: "); + print_response(sp.get_artist(artist_id)); + Serial.println("Get Artists: "); + print_response(sp.get_several_artists(artist_ids)); + Serial.println("Get Artist Albums: "); + print_response(sp.get_artist_albums(artist_id, GROUP_ALBUM +","+GROUP_SINGLE, 1, 0)); + Serial.println("Get Artist top Tracks: "); + print_response(sp.get_artist_top_tracks(artist_id)); + Serial.println("Get Artists related artists: "); + print_response(sp.get_artist_related_artist(artist_id)); +} +void test_audiobooks(){ + Serial.println("Get Audibook: "); + print_response(sp.get_audiobook(audiobook_id)); + Serial.println("Get Audibooks: "); + print_response(sp.get_several_audiobooks(audiobook_ids)); + Serial.println("Get Audibook Chapters: "); + print_response(sp.get_audiobook_chapters(audiobook_id, 1, 0)); + Serial.println("Get Users Audibooks: "); + print_response(sp.get_users_audiobooks(0, 1)); + Serial.println("Save Audibook for user: "); + print_response(sp.save_audiobooks_for_current_user(audiobook_ids)); + Serial.println("Check audiobooks: "); + print_response(sp.check_users_saved_audiobooks(audiobook_ids)); + Serial.println("Remove Audiobooks: "); + print_response(sp.remove_audiobooks_for_current_user(audiobook_ids)); +} +void test_categories(){ + Serial.println("get_several_browse_categories: "); + print_response(sp.get_several_browse_categories(country, locale)); + + Serial.println("get_single_browse_category: "); + print_response(sp.get_single_browse_category(category_id, country, locale)); +} +void test_episodes(){ + Serial.println("get_episode: "); + print_response(sp.get_episode(episode_id)); + + Serial.println("get_several_episodes: "); + print_response(sp.get_several_episodes(episode_ids)); + + Serial.println("get_users_saved_episodes: "); + print_response(sp.get_users_saved_episodes()); + + // NOT WORKING + Serial.println("save_episodes_for_current_user: "); + print_response(sp.save_episodes_for_current_user(sp.comma_separated_string_to_json(episode_ids))); + + Serial.println("check_users_saved_episodes: "); + print_response(sp.check_users_saved_episodes(episode_ids)); + + Serial.println("remove_episodes_for_current_user: "); + print_response(sp.remove_episodes_for_current_user(sp.comma_separated_string_to_json(episode_ids))); + + +} +void test_genres(){ + Serial.println("get_available_genre_seeds: "); + print_response(sp.get_available_genre_seeds()); +} +void test_markets(){ + Serial.println("get_available_markets: "); + print_response(sp.get_available_markets()); +} +void test_playlist(){ + Serial.println("get_playlist: "); + print_response(sp.get_playlist(playlist_id, fields)); + //Not working + Serial.println("change_playlist_details: "); + print_response(sp.change_playlist_details(playlist_id, "Hello", false, false, "WTF!!")); + + Serial.println("get_playlist_items: "); + print_response(sp.get_playlist_items(playlist_id, fields)); + //Not working (missing part of implementation) + Serial.println("update_playlist_items: "); + print_response(sp.update_playlist_items(playlist_id, sp.convert_id_to_uri(song_id,TYPE_TRACK))); + //not working + Serial.println("add_items_to_playlist: "); + print_response(sp.add_items_to_playlist(playlist_id, sp.convert_id_to_uri(song_id,TYPE_TRACK), 1)); + //Not working (missing part of implementation) + Serial.println("remove_playlist_items: "); + print_response(sp.remove_playlist_items(playlist_id, uris_array)); + + Serial.println("get_current_users_playlists: "); + print_response(sp.get_current_users_playlists()); + + Serial.println("get_user_playlists: "); + print_response(sp.get_user_playlists(user_id)); + + Serial.println("create_playlist: "); + print_response(sp.create_playlist(user_id, "Test", true, false, "no")); + + Serial.println("get_featured_playlists: "); + print_response(sp.get_featured_playlists(country, locale, "")); + + Serial.println("get_category_playlists: "); + print_response(sp.get_category_playlists("dinner", country)); + + Serial.println("get_playlist_cover_image: "); + print_response(sp.get_playlist_cover_image(playlist_id)); + + Serial.println("add_custom_playlist_cover_image: "); + print_response(sp.add_custom_playlist_cover_image(playlist_id, "/9j/2wCEABoZGSccJz4lJT5CLy8vQkc9Ozs9R0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0cBHCcnMyYzPSYmPUc9Mj1HR0dEREdHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR//dAAQAAf/uAA5BZG9iZQBkwAAAAAH/wAARCAABAAEDACIAAREBAhEB/8QASwABAQAAAAAAAAAAAAAAAAAAAAYBAQAAAAAAAAAAAAAAAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAARAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwAAARECEQA/AJgAH//Z")); + +} +void test_search(){ + Serial.println("search: "); + print_response(sp.search("hello+world", TYPE_TRACK)); +} +void test_shows(){ + Serial.println("get_show: "); + print_response(sp.get_show(show_id)); + + Serial.println("get_several_shows: "); + print_response(sp.get_several_shows(show_ids)); + + Serial.println("get_show_episodes: "); + print_response(sp.get_show_episodes(show_id)); + + Serial.println("get_users_saved_shows: "); + print_response(sp.get_users_saved_shows()); + + Serial.println("save_shows_for_current_user: "); + print_response(sp.save_shows_for_current_user(show_ids)); + + Serial.println("check_users_saved_shows: "); + print_response(sp.check_users_saved_shows(show_ids)); + + Serial.println("remove_shows_for_current_user: "); + print_response(sp.remove_shows_for_current_user(show_ids)); + + +} +void test_tracks(){ + Serial.println("get_track: "); + print_response(sp.get_track(track_id)); + + Serial.println("get_several_tracks: "); + print_response(sp.get_several_tracks(track_ids)); + + Serial.println("get_user_saved_tracks: "); + print_response(sp.get_user_saved_tracks()); + + Serial.println("save_tracks_for_current_user: "); + print_response(sp.save_tracks_for_current_user(sp.comma_separated_string_to_json(track_ids))); + + Serial.println("remove_user_saved_tracks: "); + print_response(sp.remove_user_saved_tracks(sp.comma_separated_string_to_json(track_ids))); + + Serial.println("check_user_saved_tracks: "); + print_response(sp.check_user_saved_tracks(track_ids)); + + Serial.println("get_tracks_audio_features: "); + print_response(sp.get_tracks_audio_features(track_ids)); + + Serial.println("get_track_audio_features: "); + print_response(sp.get_track_audio_features(track_id)); + + Serial.println("get_track_audio_analysis: "); + print_response(sp.get_track_audio_analysis(track_id)); +} +void test_users(){ + Serial.println("get_current_user_profile: "); + print_response(sp.get_current_user_profile()); + + Serial.println("get_user_top_items: "); + print_response(sp.get_user_top_items(TYPE_ARTIST, TIME_RANGE_MEDIUM)); + + Serial.println("get_user_profile: "); + print_response(sp.get_user_profile(user_id)); + + Serial.println("follow_playlist: "); + print_response(sp.follow_playlist(playlist_id, true)); + + Serial.println("unfollow_playlist: "); + print_response(sp.unfollow_playlist(playlist_id)); + + Serial.println("get_followed_artists: "); + print_response(sp.get_followed_artists("")); + + Serial.println("follow_artists_or_users: "); + print_response(sp.follow_artists_or_users(TYPE_ARTIST, sp.comma_separated_string_to_json(artist_user_ids))); + + Serial.println("unfollow_artists_or_users: "); + print_response(sp.unfollow_artists_or_users(TYPE_ARTIST, sp.comma_separated_string_to_json(artist_user_ids))); + + Serial.println("check_if_user_follows_artists_or_users: "); + print_response(sp.check_if_user_follows_artists_or_users(TYPE_ARTIST, artist_user_ids)); + + Serial.println("check_if_users_follow_playlist: "); + print_response(sp.check_if_users_follow_playlist(playlist_id, user_id)); + } \ No newline at end of file