diff --git a/SpotifyESP32.cpp b/SpotifyESP32.cpp deleted file mode 100644 index 142c1d9..0000000 --- a/SpotifyESP32.cpp +++ /dev/null @@ -1,1493 +0,0 @@ -#include "SpotifyESP32.h" -namespace Spotify_types { - bool SHUFFLE_ON = true; - bool SHUFFLE_OFF = false; - char* REPEAT_OFF = "off"; - char* REPEAT_TRACK = "track"; - char* REPEAT_CONTEXT = "context"; - char* TYPE_ALBUM = "album"; - char* TYPE_ARTIST = "artist"; - char* TYPE_TRACK = "track"; - char* TYPE_PLAYLIST = "playlist"; - char* TOP_TYPE_ARTIST = "artists"; - char* TOP_TYPE_TRACKS = "tracks"; - char* GROUP_ALBUM = "album"; - char* GROUP_SINGLE = "single"; - char* GROUP_APPEARS_ON = "appears_on"; - char* GROUP_COMPILATION = "compilation"; - char* TIME_RANGE_SHORT = "short_term"; - char* TIME_RANGE_MEDIUM = "medium_term"; - char* TIME_RANGE_LONG = "long_term"; - int SIZE_OF_ID = 40; - int SIZE_OF_URI = 50; -} - -Spotify::Spotify(const char* client_id,const char* client_secret,int server_port, bool debug_on, int max_num_retry): _server(server_port){ - _retry = 0; - _client_id = client_id; - _client_secret = client_secret; - _port = server_port; - _debug_on = debug_on; - if(max_num_retry>0){ - _max_num_retry = max_num_retry; - } - else{ - _max_num_retry = 1; - } -} - -Spotify::Spotify(const char* client_id,const char* client_secret,const char* refresh_token, bool debug_on, int max_num_retry) -{ - _port = 80; - _retry = 0; - _client_id = client_id; - _client_secret = client_secret; - strcpy(_refresh_token, refresh_token); - _debug_on = debug_on; - if(max_num_retry>0){ - _max_num_retry = max_num_retry; - } - else{ - _max_num_retry = 1; - } -} - -std::function callback_fn(Spotify *spotify) { - return [spotify]() { - return spotify->callback_login_page(); - }; -}; - -void Spotify::callback_login_page() { - if (strcmp(_refresh_token, "") == 0) { - if (_server.args() == 0) { - char page[900]; - snprintf(page,sizeof(page),_login_page, _client_id, _redirect_uri); - _server.send(200, "text/html", String(page)); - } else { - if (_server.hasArg("code")) { - _server.send(200, "text/html", "Setup Complete
You can now close this page"); - strncpy(_refresh_token, _server.arg("code").c_str(), sizeof(_refresh_token)); - if(_debug_on){ - Serial.printf("Refresh token: %s\n", _refresh_token); - } - _server.stop(); - } else { - char page[900]; - snprintf(page,sizeof(page),_login_page, _client_id, _redirect_uri); - _server.send(200, "text/html", String(page)); - } - } - } else { - _server.send(200, "text/html", "Spotify setup complete"); - _server.stop(); - } -} - -void Spotify::begin(){ - if(strcmp(_refresh_token, "") == 0){ - if(_port == 80){ - sprintf(_redirect_uri, "http://%s/", WiFi.localIP().toString().c_str()); - Serial.printf("Go to this url in your Browser to login to spotify: %s\n", _redirect_uri); - } - else{ - sprintf(_redirect_uri, "http://%s:%d/", WiFi.localIP().toString().c_str(), _port); - Serial.printf("Go to this url in your Browser to login to spotify: %s\n", _redirect_uri); - } - _server.on("/", HTTP_GET, [this](){ - if(_debug_on){ - Serial.println("Send response to Root"); - } - auto callback = callback_fn(this); - callback(); - }); - _server.begin(); - if(_debug_on){ - Serial.println("Server started"); - } - } - else{ - if(_debug_on){ - Serial.println("Refresh token already set"); - } - } -} - -void Spotify::handle_client(){ - _server.handleClient(); -} - -bool Spotify::is_auth(){ - return strcmp(_refresh_token, "") != 0; -} - -//Basic functions -response Spotify::RestApiPut(char* rest_url,int payload_size, char* payload){ - response response_obj; - init_response(&response_obj); - - HTTPClient http; - http.begin(rest_url,_spotify_root_ca); - http.addHeader("Accept", "application/json"); - http.addHeader("Content-Type", "application/json"); - http.addHeader("Authorization","Bearer "+_access_token); - http.addHeader("content-Length", String(payload_size)); - - int http_code=http.PUT(payload); - - response_obj.status_code = http_code; - String reply = ""; - DynamicJsonDocument doc(2000); - - if(http.getSize()>0){ - reply = http.getString(); - deserializeJson(doc, reply); - } - - if(_debug_on){ - const char* endpoint = extract_endpoint(rest_url); - Serial.printf("PUT \"%s\" status: ", endpoint); - Serial.println(http_code); - Serial.print(" Reply: "); - Serial.println(reply); - } - if ((http_code >= 200)&&(http_code <= 299)){ - response_obj.reply = "Success"; - } - else if(_retry<=_max_num_retry){ - String message = doc["error"]["message"].as(); - if(message == "Only valid bearer authentication supported"){ - _retry++; - if(get_token()){ - response_obj = RestApiPut(rest_url,payload_size, payload); - } - } - else{ - response_obj.reply = message; - } - } - http.end(); - _retry = 0; - - return response_obj; - -} -response Spotify::RestApiGet(char* rest_url){ - response response_obj; - init_response(&response_obj); - - HTTPClient http; - http.begin(rest_url,_spotify_root_ca); - http.addHeader("Accept", "application/json"); - http.addHeader("Content-Type", "application/json"); - http.addHeader("Authorization","Bearer "+_access_token); - int http_code = http.GET(); - - response_obj.status_code = http_code; - - if(_debug_on){ - const char* endpoint = extract_endpoint(rest_url); - Serial.printf("GET \"%s\" status: ", endpoint); - Serial.println(http_code); - Serial.print("Reply: "); - Serial.println(http.getString()); - } - if ((http_code >=200)&&(http_code<=299)){ - String response = http.getString(); - response_obj.reply = response; - } - else if(_retry<=_max_num_retry){ - _retry++; - if(get_token()){ - response_obj = RestApiGet(rest_url); - } - } - http.end(); - _retry = 0; - - return response_obj; -} -response Spotify::RestApiPost(char* rest_url,int payload_size, char* payload){ - response response_obj; - init_response(&response_obj); - - HTTPClient http; - http.begin(rest_url,_spotify_root_ca); - http.addHeader("Accept", "application/json"); - http.addHeader("Content-Type", "application/json"); - http.addHeader("Authorization","Bearer "+_access_token); - - - http.addHeader("content-Length", String(payload_size)); - int http_code=http.POST(payload); - - response_obj.status_code = http_code; - String reply = ""; - DynamicJsonDocument doc(2000); - - if(http.getSize()>0){ - reply = http.getString(); - deserializeJson(doc, reply); - } - - if(_debug_on){ - const char* endpoint = extract_endpoint(rest_url); - Serial.printf("POST \"%s\" status: ", endpoint); - Serial.println(http_code); - Serial.print(" Reply: "); - Serial.println(reply); - } - if ((http_code >= 200)&&(http_code <= 299)){ - response_obj.reply = "Success"; - } - else if(_retry<=_max_num_retry){ - String message = doc["error"]["message"].as(); - if(message == "Only valid bearer authentication supported"){ - _retry++; - if(get_token()){ - response_obj = RestApiPost(rest_url,payload_size, payload); - } - } - else{ - response_obj.reply = message; - } - } - http.end(); - _retry = 0; - - return response_obj; -} -response Spotify::RestApiDelete(char* rest_url, char* payload){ - response response_obj; - init_response(&response_obj); - - HTTPClient http; - http.begin(rest_url, _spotify_root_ca); - http.addHeader("Accept", "application/json"); - http.addHeader("Content-Type", "application/json"); - http.addHeader("Authorization", "Bearer " + _access_token); - - int http_code = http.sendRequest("DELETE", payload); - - response_obj.status_code = http_code; - String reply = ""; - DynamicJsonDocument doc(2000); - - if (http.getSize() > 0) { - reply = http.getString(); - deserializeJson(doc, reply); - } - - if (_debug_on) { - const char* endpoint = extract_endpoint(rest_url); - Serial.printf("DELETE \"%s\" status: ", endpoint); - Serial.println(http_code); - Serial.print(" Reply: "); - Serial.println(reply); - } - - if ((http_code >= 200) && (http_code <= 299)) { - response_obj.reply = "Success"; - } else if (_retry <= _max_num_retry) { - String message = doc["error"]["message"].as(); - if (message == "Only valid bearer authentication supported") { - _retry++; - if (get_token()) { - response_obj = RestApiDelete(rest_url, payload); - } - } else { - response_obj.reply = message; - } - } - - http.end(); - _retry = 0; - - return response_obj; - -} -bool Spotify::get_token(){ - bool reply = false; - HTTPClient http; - String url = "https://accounts.spotify.com/api/token"; - - String authorization = String(_client_id) + ":" + String(_client_secret); - authorization.trim(); - authorization = "Basic " + base64::encode(authorization); - http.begin(url,_spotify_root_ca); - http.addHeader("Content-Type", "application/x-www-form-urlencoded"); - http.addHeader("Authorization", authorization); - - String payload = "grant_type=refresh_token&refresh_token=" + String(_refresh_token); - int http_code = http.POST(payload); - if (_debug_on) { - Serial.print("POST \"token\" status: "); - Serial.println(http_code); - } - if ((http_code >=200)&&(http_code<=299)) { - String response = http.getString(); - StaticJsonDocument<500> doc; - deserializeJson(doc, response); - _access_token = doc["access_token"].as(); - reply = true; - } - else{ - reply = false; - } - http.end(); - return reply; -} -void Spotify::init_response(response* response_obj){ - response_obj -> status_code = -1; - response_obj -> reply ="If you see this something went wrong"; -} -char* Spotify::array_to_char(int size, char** array, char* result) { - result[0] = '\0'; - for (int i = 0; i < size; ++i) { - strcat(result, array[i]); - if (i != size - 1) { - strcat(result, ","); - } - } - return result; -} -void Spotify::array_to_json_array(int size, char** array, char* data, int data_size){ - DynamicJsonDocument doc(_max_char_size); - JsonArray json_array = doc.to(); - for (int i = 0; i char_params; - std::map float_params; - populate_float_values(float_params, recom); - populate_char_values(char_params, recom); - - for (const auto& param : char_params) { - char value[100]; - sprintf(value, "&%s%s",param.first, param.second); - strcat(url, value); - } - for(const auto& param : float_params){ - char value[100]; - sprintf(value, "&%s=%f",param.first, param.second); - strcat(url, value); - } - - return RestApiGet(url); -} -bool Spotify::is_valid_value(float param) { - return param >= 0.0 && param <= 1.0; -} -bool Spotify::is_valid_value(int param) { - return param >0; -} -void Spotify::populate_float_values(std::map& float_params, recommendations& recom){ - if (is_valid_value(recom.min_acousticness)) { - float_params["min_acousticness"] = recom.min_acousticness; - } - if (is_valid_value(recom.max_acousticness)) { - float_params["max_acousticness"] = recom.max_acousticness; - } - if (is_valid_value(recom.target_acousticness)) { - float_params["target_acousticness"] = recom.target_acousticness; - } - - if (is_valid_value(recom.min_danceability)) { - float_params["min_danceability"] = recom.min_danceability; - } - if (is_valid_value(recom.max_danceability)) { - float_params["max_danceability"] = recom.max_danceability; - } - if (is_valid_value(recom.target_danceability)) { - float_params["target_danceability"] = recom.target_danceability; - } - - if (is_valid_value(recom.min_duration_ms)) { - float_params["min_duration_ms"] = recom.min_duration_ms; - } - if (is_valid_value(recom.max_duration_ms)) { - float_params["max_duration_ms"] = recom.max_duration_ms; - } - if (is_valid_value(recom.target_duration_ms)) { - float_params["target_duration_ms"] = recom.target_duration_ms; - } - - if (is_valid_value(recom.min_energy)) { - float_params["min_energy"] = recom.min_energy; - } - if (is_valid_value(recom.max_energy)) { - float_params["max_energy"] = recom.max_energy; - } - if (is_valid_value(recom.target_energy)) { - float_params["target_energy"] = recom.target_energy; - } - - if (is_valid_value(recom.min_instrumentalness)) { - float_params["min_instrumentalness"] = recom.min_instrumentalness; - } - if (is_valid_value(recom.max_instrumentalness)) { - float_params["max_instrumentalness"] = recom.max_instrumentalness; - } - if (is_valid_value(recom.target_instrumentalness)) { - float_params["target_instrumentalness"] = recom.target_instrumentalness; - } - - if (is_valid_value(recom.min_key)) { - float_params["min_key"] = recom.min_key; - } - if (is_valid_value(recom.max_key)) { - float_params["max_key"] = recom.max_key; - } - if (is_valid_value(recom.target_key)) { - float_params["target_key"] = recom.target_key; - } - - if (is_valid_value(recom.min_liveness)) { - float_params["min_liveness"] = recom.min_liveness; - } - if (is_valid_value(recom.max_liveness)) { - float_params["max_liveness"] = recom.max_liveness; - } - if (is_valid_value(recom.target_liveness)) { - float_params["target_liveness"] = recom.target_liveness; - } - - if (is_valid_value(recom.min_loudness)) { - float_params["min_loudness"] = recom.min_loudness; - } - if (is_valid_value(recom.max_loudness)) { - float_params["max_loudness"] = recom.max_loudness; - } - if (is_valid_value(recom.target_loudness)) { - float_params["target_loudness"] = recom.target_loudness; - } - - if (is_valid_value(recom.min_mode)) { - float_params["min_mode"] = recom.min_mode; - } - if (is_valid_value(recom.max_mode)) { - float_params["max_mode"] = recom.max_mode; - } - if (is_valid_value(recom.target_mode)) { - float_params["target_mode"] = recom.target_mode; - } - - if (is_valid_value(recom.min_popularity)) { - float_params["min_popularity"] = recom.min_popularity; - } - if (is_valid_value(recom.max_popularity)) { - float_params["max_popularity"] = recom.max_popularity; - } - if (is_valid_value(recom.target_popularity)) { - float_params["target_popularity"] = recom.target_popularity; - } - - if (is_valid_value(recom.min_speechiness)) { - float_params["min_speechiness"] = recom.min_speechiness; - } - if (is_valid_value(recom.max_speechiness)) { - float_params["max_speechiness"] = recom.max_speechiness; - } - if (is_valid_value(recom.target_speechiness)) { - float_params["target_speechiness"] = recom.target_speechiness; - } - - if (is_valid_value(recom.min_tempo)) { - float_params["min_tempo"] = recom.min_tempo; - } - if (is_valid_value(recom.max_tempo)) { - float_params["max_tempo"] = recom.max_tempo; - } - if (is_valid_value(recom.target_tempo)) { - float_params["target_tempo"] = recom.target_tempo; - } - - if (is_valid_value(recom.min_time_signature)) { - float_params["min_time_signature"] = recom.min_time_signature; - } - if (is_valid_value(recom.max_time_signature)) { - float_params["max_time_signature"] = recom.max_time_signature; - } - if (is_valid_value(recom.target_time_signature)) { - float_params["target_time_signature"] = recom.target_time_signature; - } - - if (is_valid_value(recom.min_valence)) { - float_params["min_valence"] = recom.min_valence; - } - if (is_valid_value(recom.max_valence)) { - float_params["max_valence"] = recom.max_valence; - } - if (is_valid_value(recom.target_valence)) { - float_params["target_valence"] = recom.target_valence; - } -} -void Spotify::populate_char_values(std::map& char_params, recommendations& recom){ - char arr[_max_char_size]; - if(is_valid_value(recom.seed_artists_size)){ - char_params["seed_artists"] = array_to_char(recom.seed_artists_size, recom.seed_artists, arr); - } - if(is_valid_value(recom.seed_genres_size)){ - char_params["seed_genres"] = array_to_char(recom.seed_genres_size, recom.seed_genres, arr); - } - if(is_valid_value(recom.seed_tracks_size)){ - char_params["seed_tracks"] = array_to_char(recom.seed_tracks_size, recom.seed_tracks,arr); - } -} -#endif -#ifdef ENABLE_USER -//Users -response Spotify::get_current_user_profile() { - char url[] = "https://api.spotify.com/v1/me"; - - return RestApiGet(url); -} -response Spotify::get_user_top_items(char* type, char* time_range, int limit, int offset) { - char url[100]; - sprintf(url, "https://api.spotify.com/v1/me/top/%s?time_range=%s&limit=%d&offset=%d", type, time_range, limit, offset); - - return RestApiGet(url); -} -response Spotify::get_user_profile(char* user_id) { - char url[100]; - sprintf(url, "https://api.spotify.com/v1/users/%s", user_id); - - return RestApiGet(url); -} -response Spotify::follow_playlist(char* playlist_id, bool is_public) { - char url[100]; - sprintf(url, "https://api.spotify.com/v1/playlists/%s/followers", playlist_id); - char payload[100]; - int payload_size = 0; - sprintf(payload, "{\"public\":%s}", is_public ? "true" : "false"); - payload_size = strlen(payload); - - return RestApiPut(url, payload_size, payload); -} -response Spotify::unfollow_playlist(char* playlist_id) { - char url[100]; - sprintf(url, "https://api.spotify.com/v1/playlists/%s/followers", playlist_id); - - return RestApiDelete(url); -} -response Spotify::get_followed_artists(char* type, char* after, int limit) { - char url[100]; - sprintf(url, "https://api.spotify.com/v1/me/following?type=%s&after=%s&limit=%d", type, after, limit); - - return RestApiGet(url); -} -response Spotify::follow_artists_or_users(char* type,int size, char** artist_user_ids) { - char url[100]; - sprintf(url, "https://api.spotify.com/v1/me/following?type=%s", type); - char payload[_max_char_size]; - int payload_size = 0; - array_to_json_array(size, artist_user_ids, payload); - payload_size = strlen(payload); - - return RestApiPut(url, payload_size, payload); -} -response Spotify::unfollow_artists_or_users(char* type,int size, char** artist_user_ids) { - char url[100]; - sprintf(url, "https://api.spotify.com/v1/me/following?type=%s", type); - char payload[_max_char_size]; - array_to_json_array(size, artist_user_ids, payload); - - return RestApiDelete(url, payload); -} -response Spotify::check_if_user_follows_artists_or_users(char* type,int size, char** artist_user_ids) { - char url[_max_char_size]; - char arr[_max_char_size]; - sprintf(url, "https://api.spotify.com/v1/me/following/contains?type=%s&ids=%s", type, array_to_char(size, artist_user_ids, arr)); - - return RestApiGet(url); -} -response Spotify::check_if_users_follow_playlist(char* playlist_id,int size, char** user_ids) { - char url[_max_char_size]; - char arr[_max_char_size]; - sprintf(url, "https://api.spotify.com/v1/playlists/%s/followers/contains?ids=%s", playlist_id, array_to_char(size, user_ids, arr)); - - return RestApiGet(url); -} -#endif -#ifdef ENABLE_SIMPIFIED -//Simplified functions, formatting functions -String Spotify::current_track_name(){ - String track_name = "Something went wrong"; - response data = currently_playing(); - if((data.status_code>=200)&&(data.status_code<=299)){ - DynamicJsonDocument doc(10000); - deserializeJson(doc,data.reply); - track_name = doc["item"]["name"].as(); - } - return track_name; - -} -String Spotify::current_track_id(){ - String track_id = "Something went wrong"; - response data = currently_playing(); - if((data.status_code>=200)&&(data.status_code<=299)){ - DynamicJsonDocument doc(10000); - deserializeJson(doc,data.reply); - track_id = doc["item"]["id"].as(); - } - return track_id; -} -String Spotify::current_device_id(){ - String device_id = "Something went wrong"; - response data = available_devices(); - if((data.status_code>=200)&&(data.status_code<=299)){ - DynamicJsonDocument doc(2000); - deserializeJson(doc,data.reply); - JsonArray devices = doc["devices"].as(); - for (JsonVariant device : devices) { - JsonObject deviceObj = device.as(); - - if (deviceObj["is_active"].as()) { - device_id = deviceObj["id"].as(); - break; - } - } - } - return device_id; -} -String Spotify::current_artist_names(){ - String artist_names = "Something went wrong"; - response data = currently_playing(); - if((data.status_code>=200)&&(data.status_code<=299)){ - DynamicJsonDocument doc(10000); - deserializeJson(doc,data.reply); - JsonArray array = doc["item"]["artists"]; - int len = array.size(); - artist_names = ""; - for (int i = 0; i(); - if (i=200)&&(data.status_code<=299)){ - DynamicJsonDocument doc(2000); - deserializeJson(doc,data.reply); - JsonArray devices = doc["devices"].as(); - for (JsonVariant device : devices) { - JsonObject deviceObj = device.as(); - - if (deviceObj["is_active"].as()) { - sprintf(device_id, "%s", deviceObj["id"].as().c_str()); - break; - } - } - } - return device_id; -} -char* Spotify::current_track_name(char * track_name){ - response data = currently_playing(); - if((data.status_code>=200)&&(data.status_code<=299)){ - DynamicJsonDocument doc(10000); - deserializeJson(doc,data.reply); - sprintf(track_name, "%s", doc["item"]["name"].as().c_str()); - } - return track_name; -} -char* Spotify::current_track_id(char * track_id){ - response data = currently_playing(); - if((data.status_code>=200)&&(data.status_code<=299)){ - DynamicJsonDocument doc(10000); - deserializeJson(doc,data.reply); - sprintf(track_id, "%s", doc["item"]["id"].as().c_str()); - } - return track_id; -} -char* Spotify::current_artist_names(char * artist_names){ - response data = currently_playing(); - if((data.status_code>=200)&&(data.status_code<=299)){ - DynamicJsonDocument doc(10000); - deserializeJson(doc,data.reply); - JsonArray array = doc["item"]["artists"]; - int len = array.size(); - artist_names[0] = '\0'; - for (int i = 0; i().c_str()); - if (i=200)&&(data.status_code<=299)){ - DynamicJsonDocument doc(10000); - deserializeJson(doc,data.reply); - is_playing = doc["is_playing"].as(); - } - return is_playing; -} -bool Spotify::volume_modifyable(){ - bool volume_modifyable = false; - response data = current_playback_state(); - if((data.status_code>=200)&&(data.status_code<=299)){ - DynamicJsonDocument doc(10000); - deserializeJson(doc,data.reply); - volume_modifyable = doc["device"]["supports_volume"]; - } - return volume_modifyable; -} -#endif -char Spotify::convert_id_to_uri(char* id, char* type){ - char uri[45]; - sprintf(uri, "spotify:%s:%s", type, id); - return *uri; -} -char* Spotify::convert_id_to_uri(char* id, char* type,char * uri){ - sprintf(uri, "spotify:%s:%s", type, id); - return uri; -} -void print_response(response response_obj){ - Serial.printf("Status: %d\n", response_obj.status_code); - Serial.printf("Reply: %s\n", response_obj.reply); -} \ No newline at end of file diff --git a/SpotifyESP32.h b/SpotifyESP32.h deleted file mode 100644 index dedbb35..0000000 --- a/SpotifyESP32.h +++ /dev/null @@ -1,806 +0,0 @@ -#ifndef SpotifyESP32 -#define SpotifyESP32 - -#define ENABLE_PLAYER -#define ENABLE_ALBUM -#define ENABLE_ARTIST -#define ENABLE_AUDIOBOOKS -#define ENABLE_CATEGORIES -#define ENABLE_CHAPTERS -#define ENABLE_EPISODES -#define ENABLE_GENRES -#define ENABLE_MARKETS -#define ENABLE_PLAYLISTS -#define ENABLE_SEARCH -#define ENABLE_SHOWS -#define ENABLE_TRACKS -#define ENABLE_USER -#define ENABLE_SIMPIFIED - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - - - - -namespace Spotify_types { - extern bool SHUFFLE_ON; - extern bool SHUFFLE_OFF; - extern char* REPEAT_OFF; - extern char* REPEAT_TRACK; - extern char* REPEAT_CONTEXT; - extern char* TYPE_ALBUM; - extern char* TYPE_ARTIST; - extern char* TYPE_TRACK; - extern char* TYPE_PLAYLIST; - extern char* TOP_TYPE_ARTIST; - extern char* TOP_TYPE_TRACKS; - extern char* GROUP_ALBUM; - extern char* GROUP_SINGLE; - extern char* GROUP_APPEARS_ON; - extern char* GROUP_COMPILATION; - extern char* TIME_RANGE_SHORT; - extern char* TIME_RANGE_MEDIUM; - extern char* TIME_RANGE_LONG; - extern int SIZE_OF_ID; - extern int SIZE_OF_URI; - -} - -/// @brief Response object containing http status code and reply -typedef struct{ - int status_code; - String reply; -} response; - -/// @brief Recommendation object, used to create recommendations -struct recommendations { - char** seed_artists; - int seed_artists_size = 0; - char** seed_genres; - int seed_genres_size = 0; - char** seed_tracks; - int seed_tracks_size = 0; - float min_acousticness = -1.0; - float max_acousticness = -1.0; - float target_acousticness = -1.0; - float min_danceability = -1.0; - float max_danceability = -1.0; - float target_danceability = -1.0; - float min_duration_ms = -1.0; - float max_duration_ms = -1.0; - float target_duration_ms = -1.0; - float min_energy = -1.0; - float max_energy = -1.0; - float target_energy = -1.0; - float min_instrumentalness = -1.0; - float max_instrumentalness = -1.0; - float target_instrumentalness = -1.0; - float min_key = -1.0; - float max_key = -1.0; - float target_key = -1.0; - float min_liveness = -1.0; - float max_liveness = -1.0; - float target_liveness = -1.0; - float min_loudness = -1.0; - float max_loudness = -1.0; - float target_loudness = -1.0; - float min_mode = -1.0; - float max_mode = -1.0; - float target_mode = -1.0; - float min_popularity = -1.0; - float max_popularity = -1.0; - float target_popularity = -1.0; - float min_speechiness = -1.0; - float max_speechiness = -1.0; - float target_speechiness = -1.0; - float min_tempo = -1.0; - float max_tempo = -1.0; - float target_tempo = -1.0; - float min_time_signature = -1.0; - float max_time_signature = -1.0; - float target_time_signature = -1.0; - float min_valence = -1.0; - float max_valence = -1.0; - float target_valence = -1.0; -}; - -/// @brief Print response object -/// @param response_obj Response object to print -void print_response(response response_obj); -class Spotify { - public: - ///@brief Constructor for Spotify object without refresh token - ///@param client_id Client id from Spotify(Required) - ///@param client_secret Client secret from Spotify(Required) - ///@param server_port Port for the server to run on(default 80, if 80 is already used use anything above 1024) - ///@param debug_on Debug mode on or off(default off) - ///@param max_num_retry Max number of retries for a request(default 3) - Spotify(const char* client_id,const char* client_secret, int server_port = 80, bool debug_on = false, int max_num_retry = 3); - ///@brief Constructor for Spotify object with refresh token - ///@param client_id Client id from Spotify(Required) - ///@param client_secret Client secret from Spotify(Required) - ///@param refresh_token Refresh token from Spotify(Required) if not authenticated use other constructor - ///@param debug_on Debug mode on or off(default off) - ///@param max_num_retry Max number of retries for a request(default 3) - Spotify(const char* client_id,const char* client_secret,const char* refresh_token, bool debug_on = false, int max_num_retry = 3); - /// @brief start the server and begin authentication - void begin(); - /// @brief handle client requests necessary for authentication - void handle_client(); - ///@brief Check if user is authenticated - ///@return true if user is authenticated - bool is_auth(); - #ifdef ENABLE_PLAYER - ///@brief Get information about the user's current playback state, including track, track progress, and active device. - ///@return response object containing http status code and reply - response currently_playing(); - ///@brief Start or resume playback. If no device_id is provided, the user's currently active device is the target. - ///@param context_uri Spotify URI of the context to play (Required) - ///@param offset Indicates from where in the context playback should start, Only works with albums or Playlists. NEEDS TO BE SET (0) IF ONLY URI IS PROVIDED - ///@param position_ms Indicates from what position in the context playback should start in milliseconds(Optional) - ///@param device_id Id of the device this command is targeting (Optional) - ///@return response object containing http status code and reply - response start_resume_playback(char* context_uri, int offset, int position_ms = 0, char* device_id = nullptr); - ///@brief Start or resume playback. If no device_id is provided, the user's currently active device is the target. - ///@param size Number of uris in uris array - ///@param uris Array of Spotify URIs of the tracks to play - ///@param device_id Id of the device this command is targeting (Optional) - ///@return response object containing http status code and reply - response start_resume_playback(int size, char ** uris ,char* device_id = nullptr); - ///@brief Start or resume playback. If no device_id is provided, the user's currently active device is the target. Targets the currently playing context. - ///@return response object containing http status code and reply - response start_resume_playback(char* device_id = nullptr); - ///@brief Pause playback on Spotify - ///@return response object containing http status code and reply - response pause_playback(); - ///@brief Skip to next track - ///@return response object containing http status code and reply - response skip(); - ///@brief Skip to previous track - ///@return response object containing http status code and reply - response previous(); - ///@brief get information about the user's available devices - ///@return response object containing http status code and reply - response available_devices(); - ///@brief get information about the user's current playback state, including track, track progress, and active device, shuffle etc. - ///@return response object containing http status code and reply - response current_playback_state(); - ///@brief Get recently played tracks - ///@param limit The maximum number of items to return. Default: 10. Minimum: 1. Maximum: 50 - response recently_played_tracks(int limit = 10); - ///@brief Seek to position of current context - ///@param time_ms Position in milliseconds to seek to, if the value is greater than the length of the track the player will skip to the next track - ///@return response object containing http status code and reply - response seek_to_position(int time_ms); - ///@brief get users queue, response can be empty or containing episode or track objects - ///@return response object containing http status code and reply - response get_queue(); - ///@Brief Set repeat mode, allowed values are REPEAT_OFF, REPEAT_TRACK, REPEAT_CONTEXT - ///@param mode Repeat mode - ///@return response object containing http status code and reply - response repeat_mode(char* mode); - ///@Brief Set shuffle mode, allowed values are SHUFFLE_ON, SHUFFLE_OFF - ///@param mode Shuffle mode - ///@return response object containing http status code and reply - response shuffle(bool mode); - ///@Brief Transfer playback to another device - ///@param device_id Id of the device this command is targeting - ///@return response object containing http status code and reply - response transfer_playback(char* device_id); - ///@Brief Set volume, does not work with all devices(eg. does not work on Phones) - ///@param value Volume value between 0 and 100 - ///@return response object containing http status code and reply - response set_volume(int value); - ///@Brief Add context to queue - ///@param context_uri Spotify URI of the context to add to queue - response add_to_queue(char* context_uri); - #endif - #ifdef ENABLE_ALBUM - ///@brief Get Spotify information for a single album. - ///@param album_id Spotify ID of the album - ///@return response object containing http status code and reply - response get_album(char* album_id); - ///@brief Get Spotify information for multiple albums identified by their Spotify IDs. - ///@param size Number of album ids in album_ids array - ///@param album_ids Array of Spotify IDs of the albums - ///@return response object containing http status code and reply - response get_albums(int size, char** album_ids); - ///@brief Get Spotify information about an album's tracks. - ///@param album_id Spotify ID of the album - ///@param limit The maximum number of tracks to return. Default: 10. Minimum: 1. Maximum: 50 - ///@param offset The index of the first track to return. Default: 0 (the first object). Use with limit to get the next set of tracks. - ///@return response object containing http status code and reply - response get_album_tracks(char* album_id, int limit = 10, int offset = 0); - ///@brief Get Albums saved to the current user's music library. - ///@param limit The maximum number of albums to return. Default: 10. Minimum: 1. Maximum: 50 - ///@param offset The index of the first album to return. Default: 0 (the first object). Use with limit to get the next set of albums. - ///@return response object containing http status code and reply - response get_users_saved_albums(int limit = 10, int offset = 0); - ///@brief Save one or more albums to the current user's music library. - ///@param size Number of album ids in album_ids array - ///@param album_ids Array of Spotify IDs of the albums - ///@return response object containing http status code and reply - response save_albums_for_current_user(int size, char** album_ids); - ///@brief Remove one or more albums from the current user's music library. - ///@param size Number of album ids in album_ids array - ///@param album_ids Array of Spotify IDs of the albums - ///@return response object containing http status code and reply - response remove_users_saved_albums(int size, char** album_ids); - ///@brief Check if one or more albums is already saved in the current Spotify user's music library. - ///@param size Number of album ids in album_ids array - ///@param album_ids Array of Spotify IDs of the albums - ///@return response object containing http status code and reply - response check_useres_saved_albums(int size, char** album_ids); - ///@brief Get a list of new album releases featured in Spotify - ///@param limit The maximum number of items to return. Default: 10. Minimum: 1. Maximum: 50 - ///@param offset The index of the first item to return. Default: 0 (the first object). Use with limit to get the next set of items. - ///@param country A country: an ISO 3166-1 alpha-2 country code. Provide this parameter if you want the list of returned items to be relevant to a particular country. - ///@return response object containing http status code and reply - response get_new_releases(int limit = 10, int offset = 0, char* country = nullptr); - #endif - #ifdef ENABLE_ARTIST - ///@brief Get Spotify information for a single artist - ///@param artist_id Spotify ID of the artist - ///@return response object containing http status code and reply - response get_artist(char* artist_id); - ///@brief Get Spotify information for multiple artists - ///@param size Number of artist ids in artist_ids array - ///@param artist_ids Array of Spotify IDs of the artists - ///@return response object containing http status code and reply - response get_several_artists(int size, char** artist_ids); - ///@brief Get Spotify information about an artist's albums - ///@param artist_id Spotify ID of the artist - ///@param size_groups Number of groups in include_groups array - ///@param include_groups Array of groups to include in the response. Valid values are GROUP_ALBUM, GROUP_SINGLE, GROUP_APPEARS_ON, GROUP_COMPILATION or any combination of these. - ///@param limit The maximum number of items to return. Default: 10. Minimum: 1. Maximum: 50 - ///@param offset The index of the first album to return. Default: 0 (the first object). Use with limit to get the next set of albums. - ///@return response object containing http status code and reply - response get_artist_albums(char* artist_id,int size_groups, char** include_groups, int limit = 10, int offset = 0); - ///@brief Get Spotify information about an artist's top tracks - ///@param artist_id Spotify ID of the artist - ///@param country An ISO 3166-1 alpha-2 country code or the string from_token. Provide this parameter if you want the list of returned items to be relevant to a particular country. - ///@return response object containing http status code and reply - response get_artist_top_tracks(char* artist_id, char* country = nullptr); - ///@brief Get Spotify information about artists related to a single artist - ///@param artist_id Spotify ID of the artist - ///@return response object containing http status code and reply - response get_artist_related_artist(char* artist_id); - #endif - #ifdef ENABLE_AUDIOBOOKS - ///@brief Get Spotify information for a single audiobook(Only Available in US, UK, Canada, Ireland, New Zealand and Australia) - ///@param audiobook_id Spotify ID of the audiobook - ///@return response object containing http status code and reply - response get_audiobook(char* audiobook_id); - ///@brief Get Spotify information for multiple audiobooks(Only Available in US, UK, Canada, Ireland, New Zealand and Australia) - ///@param size Number of audiobook ids in audiobook_ids array - ///@param audiobook_ids Array of Spotify IDs of the audiobooks - ///@return response object containing http status code and reply - response get_several_audiobooks(int size, char** audiobook_ids); - ///@brief Get Spotify information about an audiobook's chapters(Only Available in US, UK, Canada, Ireland, New Zealand and Australia) - ///@param audiobook_id Spotify ID of the audiobook - ///@param limit The maximum number of items to return. Default: 10. Minimum: 1. Maximum: 50 - ///@param offset The index of the first chapter to return. Default: 0 (the first object). Use with limit to get the next set of chapters. - ///@return response object containing http status code and reply - response get_audiobook_chapters(char* audiobook_id, int limit = 10, int offset = 0); - /// @brief Get users saved audiobooks(Only Available in US, UK, Canada, Ireland, New Zealand and Australia) - /// @param limit The maximum number of items to return - /// @param offset The index of the first item to return - /// @return response object containing http status code and reply - response get_users_audiobooks(int limit = 10, int offset = 0); - /// @brief Save one or more audiobooks to the current user's music library(Only Available in US, UK, Canada, Ireland, New Zealand and Australia) - /// @param size Number of audiobook ids in audiobook_ids array - /// @param audiobook_ids Array of Spotify IDs of the audiobooks - /// @return response object containing http status code and reply - response save_audiobooks_for_current_user(int size, char** audiobook_ids); - /// @brief Remove one or more audiobooks from the current user's music library(Only Available in US, UK, Canada, Ireland, New Zealand and Australia) - /// @param size Number of audiobook ids in audiobook_ids array - /// @param audiobook_ids Array of Spotify IDs of the audiobooks - /// @return response object containing http status code and reply - response remove_audiobooks_for_current_user(int size, char** audiobook_ids); - /// @brief Check if one or more audiobooks is already saved in the current Spotify user's music library(Only Available in US, UK, Canada, Ireland, New Zealand and Australia) - /// @param size Number of audiobook ids in audiobook_ids array - /// @param audiobook_ids Array of Spotify IDs of the audiobooks - /// @return response object containing http status code and reply - response check_users_saved_audiobooks(int size, char** audiobook_ids); - #endif - #ifdef ENABLE_CATEGORIES - ///@brief Get a list of categories used to tag items in Spotify - ///@param limit The maximum number of items to return - ///@param offset The index of the first item to return - ///@param country An ISO 3166-1 alpha-2 country code, if ommited the returned items will not be country-specific - ///@param locale The desired language, consisting of an ISO 639-1 language code and an ISO 3166-1 alpha-2 country code, joined by an underscore, if ommited the response defaults to American English - ///@return response object containing http status code and reply - response get_several_browse_categories(int limit = 10, int offset = 0, char* country = nullptr, char* locale = nullptr); - ///@brief Get a single category used to tag items in Spotify - ///@param category_id Spotify category ID of the category - ///@param country An ISO 3166-1 alpha-2 country code, if ommited the returned items will not be country-specific - ///@param locale The desired language, consisting of an ISO 639-1 language code and an ISO 3166-1 alpha-2 country code, joined by an underscore, if ommited the response defaults to American English - ///@return response object containing http status code and reply - response get_single_browse_category(char* category_id, char* country = nullptr, char* locale = nullptr); - #endif - #ifdef ENABLE_CHAPTERS - ///@brief Get Spotify information for a single chapter, Only Available in US, UK, Canada, Ireland, New Zealand and Australia - ///@param chapter_id Spotify ID of the chapter - ///@return response object containing http status code and reply - response get_chapter(char* chapter_id); - ///@brief Get Spotify information for multiple chapters, Only Available in US, UK, Canada, Ireland, New Zealand and Australia - ///@param size Number of chapter ids in chapter_ids array - ///@param chapter_ids Array of Spotify IDs of the chapters - ///@return response object containing http status code and reply - response get_several_chapters(int size, char** chapter_ids); - #endif - #ifdef ENABLE_EPISODES - ///@brief Get Spotify information for a single episode - ///@param episode_id Spotify ID of the episode - ///@return response object containing http status code and reply - response get_episode(char* episode_id); - ///@brief Get Spotify information for multiple episodes - ///@param size Number of episode ids in episode_ids array - ///@param episode_ids Array of Spotify IDs of the episodes - ///@return response object containing http status code and reply - response get_several_episodes(int size, char** episode_ids); - ///@brief Get users saved episodes - ///@param limit The maximum number of items to return, - ///@param offset The index of the first item to return - ///@return response object containing http status code and reply - response get_users_saved_episodes(int limit = 10, int offset = 0); - ///@brief Save one or more episodes to the current user's music library - ///@param size Number of episode ids in episode_ids array - ///@param episode_ids Array of Spotify IDs of the episodes - ///@return response object containing http status code and reply - response save_episodes_for_current_user(int size, char** episode_ids); - ///@brief Remove one or more episodes from the current user's music library - ///@param size Number of episode ids in episode_ids array - ///@param episode_ids Array of Spotify IDs of the episodes - ///@return response object containing http status code and reply - response remove_episodes_for_current_user(int size, char** episode_ids); - ///@brief Check if one or more episodes is already saved in the current Spotify user's music library - ///@param size Number of episode ids in episode_ids array - ///@param episode_ids Array of Spotify IDs of the episodes - ///@return response object containing http status code and reply - response check_users_saved_episodes(int size, char** episode_ids); - #endif - #ifdef ENABLE_GENRES - ///@brief Get a list of available genre seeds for recommendations - ///@return response object containing http status code and reply - response get_available_genre_seeds(); - #endif - #ifdef ENABLE_MARKETS - ///@brief Get a list of available markets for recommendations - ///@return response object containing http status code and reply - response get_available_markets(); - #endif - #ifdef ENABLE_PLAYLISTS - ///@brief Get Spotify information for a single playlist - ///@param playlist_id Spotify ID of the playlist - ///@param size Number of fields in fields array - ///@param fields Array of fields to return, leave empty to return all fields - ///@param additional_types A comma-separated list of item types that your client supports besides the default track type. Valid types are: track and episode. - ///@return response object containing http status code and reply - response get_playlist(char* playlist_id,int size = 0, char** fields = nullptr,int size_of_additional_types = 0, char ** additional_types = nullptr); - /// @brief Change details of a playlist - /// @param playlist_id ID of the playlist - /// @param name Set the name of the playlist - /// @param is_public Set the playlist to public or not - /// @param is_collaborative Set the playlist to collaborative or not - /// @param description Set the description of the playlist - /// @return response object containing http status code and reply - response change_playlist_details(char* playlist_id, char* name, bool is_public, bool is_collaborative, char* description); - /// @brief Get Items of a playlist - /// @param playlist_id Id of the playlist - /// @param fields Filters for the query: a comma-separated list of the fields to return. If omitted, all fields are returned. For example, to get just the total number of items and the request limit: - /// @param limit Number of items to return - /// @param offset The index of the first item to return - /// @return response object containing http status code and reply - response get_playlist_items(char* playlist_id, char* fields, int limit = 10, int offset = 0); - /// @brief Either reorder or replace items in a playlist depending on the request's parameters - /// @param playlist_id Id of the playlist - /// @param size Size of uris array - /// @param uris Array of Spotify URIs this will overwrite all existing items in the playlist, If items should only be reordered pass nullptr - /// @param range_length The position of the first item to be reordered. - /// @param range_start The position where the items should be inserted. - /// @param insert_before The amount of items to be reordered. - /// @return response object containing http status code and reply - response update_playlist_items(char* playlist_id, int size, char** uris = nullptr, int range_length = 1, int range_start = 0, int insert_before = 1 ); - /// @brief Add items to a playlist - /// @param playlist_id Id of the playlist - /// @param size Size of uris array - /// @param uris Array of Spotify URIs of the items to add - /// @param position The position to insert the items, a zero-based index - /// @return response object containing http status code and reply - response add_items_to_playlist(char* playlist_id, int size, char** uris, int position = 0); - /// @brief Remove items from a playlist - /// @param playlist_id Id of the playlist - /// @param size Size of uris array - /// @param uris Array of Spotify URIs of the items to remove - /// @return response object containing http status code and reply - response remove_playlist_items(char* playlist_id, int size, char** uris); - /// @brief Get a list of users playlists - /// @param limit The maximum number of items to return - /// @param offset The index of the first item to return - /// @return response object containing http status code and reply - response get_current_users_playlists(int limit = 10, int offset = 0); - /// @brief get a users playlist - /// @param user_id Id of the user - /// @param limit The maximum number of items to return - /// @param offset The index of the first item to return - /// @return response object containing http status code and reply - response get_user_playlists(char* user_id,int limit = 10, int offset = 0); - /// @brief Create a playlist - /// @param user_id Id of the user - /// @param name Name of the playlist - /// @param is_public Set the playlist to public or not - /// @param is_collaborative Set the playlist to collaborative or not - /// @param description Description of the playlist - /// @return response object containing http status code and reply - response create_playlist(char* user_id, char* name, bool is_public, bool is_collaborative, char* description); - /// @brief Get a list of Spotify featured playlists - /// @param limit The maximum number of items to return - /// @param offset The index of the first item to return - /// @param timestamp A timestamp in ISO 8601 format: yyyy-MM-ddTHH:mm:ss if ommited current utc time is used - /// @param country An ISO 3166-1 alpha-2 country code, Provide this to ensure that the category exists for a particular country. - /// @param locale The desired language, consisting of an ISO 639-1 language code and an ISO 3166-1 alpha-2 country code, joined by an underscore, if ommited the response defaults to American English - /// @return response object containing http status code and reply - response get_featured_playlists( int limit = 10, int offset = 0, char* timestamp = nullptr, char* country = nullptr, char* locale = nullptr); - /// @brief Get a list of Spotify playlists tagged with a particular category. - /// @param category_id Category ID can be got from get_several_browse_categories - /// @param limit The maximum number of items to return - /// @param offset The index of the first item to return - /// @param country The country: an ISO 3166-1 alpha-2 country code, Provide this to ensure that the category exists for a particular country. - /// @return response object containing http status code and reply - response get_category_playlists(char* category_id, int limit = 10, int offset = 0, char* country = nullptr); - /// @brief Get a cover image of a playlist - /// @param playlist_id Id of the playlist - /// @return response object containing http status code and reply - response get_playlist_cover_image(char* playlist_id); - /// @brief Upload a custom cover image of a playlist - /// @param playlist_id Id of the playlist - /// @param data Image data - /// @param market An ISO 3166-1 alpha-2 country code, Provide this parameter if you want to apply Track Relinking - /// @return response object containing http status code and reply - response add_custom_playlist_cover_image(char* playlist_id, char* data); - #endif - #ifdef ENABLE_SEARCH - /// @brief Search for an item - /// @param q Search query keywords and optional field filters and operators - /// @param type_size Number of item types in type array,needs to e set to 0 if limit, offset or market is used and type is not used - /// @param type A comma-separated list of item types to search across, needs to be set to nullptr if limit, offset or market is used and type is not used - /// @param limit The maximum number of items to return - /// @param offset The index of the first item to return - /// @param market An ISO 3166-1 alpha-2 country code or the string from_token, Provide this parameter if you want to apply Track Relinking - /// @return response object containing http status code and reply - response search(char* q,int type_size = 0, char** type = nullptr, int limit = 10, int offset = 0, char* market = nullptr); - #endif - #ifdef ENABLE_SHOWS - /// @brief Get Spotify information for a single show - /// @param show_id Spotify ID of the show - /// @return response object containing http status code and reply - response get_show(char* show_id); - /// @brief Get Spotify information for multiple shows - /// @param size Number of show ids in show_ids array - /// @param show_ids Array of Spotify IDs of the shows - /// @return response object containing http status code and reply - response get_several_shows(int size, char** show_ids); - /// @brief Get Spotify information about a show's episodes - /// @param show_id Spotify ID of the show - /// @param limit The maximum number of items to return - /// @param offset The index of the first item to return - /// @return response object containing http status code and reply - response get_show_episodes(char* show_id, int limit = 10, int offset = 0); - /// @brief Get users saved shows - /// @param limit The maximum number of items to return - /// @param offset The index of the first item to return - /// @return response object containing http status code and reply - response get_users_saved_shows(int limit = 10, int offset = 0); - /// @brief Save one or more shows to the current user's music library - /// @param size Number of show ids in show_ids array - /// @param show_ids Array of Spotify IDs of the shows - /// @return response object containing http status code and reply - response save_shows_for_current_user(int size, char** show_ids); - /// @brief Remove one or more shows from the current user's music library - /// @param size Number of show ids in show_ids array - /// @param show_ids Array of Spotify IDs of the shows - /// @return response object containing http status code and reply - response remove_shows_for_current_user(int size, char** show_ids); - /// @brief Check if one or more shows is already saved in the current Spotify user's music library - /// @param size Number of show ids in show_ids array - /// @param show_ids Array of Spotify IDs of the shows - /// @return response object containing http status code and reply - response check_users_saved_shows(int size, char** show_ids); - #endif - #ifdef ENABLE_TRACKS - /// @brief Get Spotify information for a single track - /// @param track_id Spotify ID of the track - /// @return response object containing http status code and reply - response get_track(char* track_id); - /// @brief Get Spotify information for multiple tracks - /// @param size Number of track ids in track_ids array - /// @param track_ids Array of Spotify IDs of the tracks - /// @return response object containing http status code and reply - response get_several_tracks(int size, char** track_ids); - /// @brief Get users saved tracks - /// @param limit The maximum number of items to return - /// @param offset The index of the first item to return - /// @return response object containing http status code and reply - response get_user_saved_tracks(int limit = 10, int offset = 0); - /// @brief Save one or more tracks to the current user's music library - /// @param size Number of track ids in track_ids array - /// @param track_ids Array of Spotify IDs of the tracks - /// @return response object containing http status code and reply - response save_tracks_for_current_user(int size, char** track_ids); - /// @brief Remove one or more tracks from the current user's music library - /// @param size Number of track ids in track_ids array - /// @param track_ids Array of Spotify IDs of the tracks - /// @return response object containing http status code and reply - response remove_user_saved_tracks(int size, char** track_ids); - /// @brief Check if one or more tracks is already saved in the current Spotify user's music library - /// @param size Number of track ids in track_ids array - /// @param track_ids Array of Spotify IDs of the tracks - /// @return response object containing http status code and reply - response check_user_saved_tracks(int size, char** track_ids); - /// @brief Get audio features for multiple tracks - /// @param size Number of track ids in track_ids array - /// @param track_ids Array of Spotify IDs of the tracks - /// @return response object containing http status code and reply - response get_tracks_audio_features(int size, char** track_ids); - /// @brief Get audio features for a single track - /// @param track_id Spotify ID of the track - /// @return response object containing http status code and reply - response get_track_audio_features(char* track_id); - /// @brief Get audio analysis for a single track - /// @param track_id Spotify ID of the track - /// @return response object containing http status code and reply - response get_track_audio_analysis(char* track_id); - /// @brief Get a list of new album releases featured in Spotify - /// @param recom Recommendation object containing atleast one seed - /// @param limit The maximum number of items to return - /// @return response object containing http status code and reply - response get_recommendations(recommendations& recom, int limit = 10); - #endif - #ifdef ENABLE_USER - /// @brief Get detailed profile information about the current user (including the current user's username) - /// @return response object containing http status code and reply - response get_current_user_profile(); - /// @brief Get users top items - /// @param type The type of item to get, Valid values are: artists or tracks - /// @param time_range Over what time frame the affinities are computed, Valid values are: long_term, medium_term, short_term - /// @param limit The maximum number of items to return - /// @param offset The index of the first item to return - /// @return response object containing http status code and reply - response get_user_top_items(char* type, char* time_range = "medium_term", int limit = 10, int offset = 0); - /// @brief Get a users profile - /// @param user_id Id of the user - /// @return response object containing http status code and reply - response get_user_profile(char* user_id); - /// @brief Follow a playlist - /// @param playlist_id The Id of the playlist - /// @param is_public If true the playlist will be included in user's public playlists, if false it will remain private. - /// @return response object containing http status code and reply - response follow_playlist(char* playlist_id, bool is_public); - /// @brief Unfollow a playlist - /// @param playlist_id The Id of the playlist - /// @return response object containing http status code and reply - response unfollow_playlist(char* playlist_id); - /// @brief get users followed artists - /// @param after The last artist ID retrieved from the previous request - /// @param type The ID type, currently only artist is supported - /// @param limit The maximum number of items to return - /// @return response object containing http status code and reply - response get_followed_artists(char* after, char* type = "artist", int limit = 10); - /// @brief Follow artists or users - /// @param type The ID type, artist or user - /// @param size Number of artist or user ids in artist_user_ids array - /// @param artist_user_ids Array of Spotify IDs of the artists or users - /// @return response object containing http status code and reply - response follow_artists_or_users(char* type, int size, char** artist_user_ids); - /// @brief Unfollow artists or users - /// @param type The ID type, artist or user - /// @param size Number of artist or user ids in artist_user_ids array - /// @param artist_user_ids Array of Spotify IDs of the artists or users - /// @return response object containing http status code and reply - response unfollow_artists_or_users(char* type, int size, char** artist_user_ids); - /// @brief Check if users follow artists or users - /// @param type The ID type, artist or user - /// @param size Number of artist or user ids in artist_user_ids array - /// @param artist_user_ids Array of Spotify IDs of the artists or users - /// @return response object containing http status code and reply - response check_if_user_follows_artists_or_users(char* type, int size, char** artist_user_ids); - /// @brief Check if users follow a playlist - /// @param playlist_id The ID of the playlist - /// @param size Number of user ids in user_ids array - /// @param user_ids Array of Spotify IDs of the users - /// @return response object containing http status code and reply - response check_if_users_follow_playlist(char* playlist_id, int size, char** user_ids); - #endif - #ifdef ENABLE_SIMPIFIED - /// @brief Get Current track name - /// @return Current track name as String - String current_track_name(); - /// @brief Get Current track id - /// @return Current track id as String - String current_track_id(); - /// @brief Get Current device id - /// @return Current device id as String - String current_device_id(); - /// @brief Get Current artist names - /// @return Current artist names as String - String current_artist_names(); - /// @brief Get Current device id - /// @param char array to store device id - /// @return Current device id as pointer to char array - char* current_device_id(char* device_id); - /// @brief Get Current track id - /// @param char array to store track id - /// @return Current track id as pointer to char array - char* current_track_id(char* track_id); - /// @brief Get Current track name - /// @param char array to store track name - /// @return Current track name as pointer to char array - char* current_track_name(char* track_name); - /// @brief Get Current artist names - /// @param char array to store artist names - /// @return Current artist names as pointer to char array - char* current_artist_names(char* artist_names); - /// @brief Get if device is playing - /// @return true if device is playing - bool is_playing(); - /// @brief Get if it is possible to modify volume on current device - /// @return true if it is possible to modify volume on current device - bool volume_modifyable(); - #endif - /// @brief Convert ID to URI - /// @param id ID to convert - /// @param type Type of ID - /// @return URI as char - char convert_id_to_uri(char* id, char* type); - /// @brief Convert ID to URI - /// @param id ID to convert - /// @param type Type of ID - /// @param uri char array to store URI - /// @return URI as pointer to char array - char* convert_id_to_uri(char* id, char* type, char* uri); - - private: - WebServer _server; - /// @brief Maximum number of items in one request - static const int _max_num_items = 20; - /// @brief Maximum size of char array(35 been the size of a uri + comma + 150 as buffer for url etc.) - static const int _max_char_size = 35*_max_num_items + 150; - /// @brief Size of a uri - static const int _size_of_uri = 45; - /// @brief Size of an id - static const int _size_of_id = 25; - /// @brief Maximum number of items in one request - int _max_num_retry = 3; - /// @brief Users refresh token - char _refresh_token[300] = ""; - /// @brief Users set redirect uri - char _redirect_uri[100] = ""; - /// @brief Users set client id - const char* _client_id; - /// @brief Users set client secret - const char* _client_secret; - /// @brief Current number of retries - int _retry; - /// @brief Debug mode - bool _debug_on; - /// @brief port - int _port; - /// @brief Access token - String _access_token; - /// @brief Callback function for login page - void callback_login_page(); - friend std::function callback_fn(Spotify *spotify); - /// @brief Get Access Token with refresh token - /// @return Bool if token was successfully retrieved - bool get_token(); - /// @brief Initialize response object - /// @param response_obj Response object to initialize - void init_response(response* response_obj); - /// @brief Make PUT request to Spotify API - /// @param rest_url URL to make request to - /// @param payload_size Size of payload - /// @param payload Payload to send - /// @return Response object containing http status code and reply - response RestApiPut(char* rest_url, int payload_size = 0, char* payload = nullptr); - /// @brief Make POST request to Spotify API - /// @param rest_url URL to make request to - /// @param payload_size Size of payload - /// @param payload Payload to send - /// @return Response object containing http status code and reply - response RestApiPost(char* rest_url, int payload_size = 0, char* payload = nullptr); - /// @brief Make DELETE request to Spotify API - /// @param rest_url URL to make request to - /// @param payload Payload to send - /// @return Response object containing http status code and reply - response RestApiDelete(char* rest_url, char* payload = nullptr); - /// @brief Make GET request to Spotify API - /// @param rest_url URL to make request to - /// @return Response object containing http status code and reply - response RestApiGet(char* rest_url); - /// @brief Convert array of chars to one char array, seperated by comma - /// @param size Size of array - /// @param array Array to convert - /// @param result Array to store result - /// @return Pointer to result array - char* array_to_char(int size, char** array, char* result); - /// @brief Convert array of chars to one json array - /// @param size Size of array - /// @param array Array to convert - /// @param data Array to store result - /// @param data_size Size of data array - /// @return Pointer to data array - void array_to_json_array(int size, char** array, char* data, int data_size = _max_char_size);//Convert array of chars to one json array - #ifdef ENABLE_TRACKS - /// @brief Check if recommendation value is valid - /// @param param Float value to check - /// @return Bool if value is valid - bool is_valid_value(float param); - /// @brief Check if recommendation value is valid - /// @param param Int value to check - /// @return Bool if value is valid - bool is_valid_value(int param); - /// @brief Populate recommendation char values - /// @param map Map to populate - /// @param recom recommendation object - /// @return Void - void populate_char_values(std::map& map, recommendations& recom); - /// @brief Populate recommendation float values - /// @param map Map to populate - /// @param recom recommendation object - /// @return Void - void populate_float_values(std::map& map, recommendations& recom); - #endif - /// @brief Extract endpoint from url with regex - const char * extract_endpoint(const char* rest_url); - /// @brief Root CA for Spotify API - const char* _spotify_root_ca PROGMEM = \ - "-----BEGIN CERTIFICATE-----\n" \ - "MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh\n" \ - "MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n"\ - "d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD\n"\ - "QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT\n"\ - "MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j\n"\ - "b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG\n"\ - "9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB\n"\ - "CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97\n"\ - "nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt\n"\ - "43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P\n"\ - "T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4\n"\ - "gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO\n"\ - "BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR\n"\ - "TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw\n"\ - "DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr\n"\ - "hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg\n"\ - "06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF\n"\ - "PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls\n"\ - "YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk\n"\ - "CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=\n"\ - "-----END CERTIFICATE-----\n"; - const char* _login_page PROGMEM = R"=====( - - - ESP Spotify Login - - -
-

Spotify Login

- Log in to spotify -
- - - )====="; -}; -#endif \ No newline at end of file diff --git a/main.cpp b/main.cpp deleted file mode 100644 index b2ebefd..0000000 --- a/main.cpp +++ /dev/null @@ -1,41 +0,0 @@ -#include -#include -#include "SpotifyESP32.h" -const char* ssid = "Rebweg10D"; -const char* password = "Bitte_eintreten"; -const char* client_id = "fc0799459cf04f1aab6bb3f861964e77"; -const char* client_secret = "9ca64f76f7b54ecdaf3ae78585ff8b0f"; -int port = 8000; -const char* refresh_token = "AQAlYkKcfHdrul3u451q32Wl0Fy4HWcmh0Mbyerl1-8V3eKmDADpYhCYBXAeAHbPjadhNqULx8cNyfhUkwSh-dmIo27IY1kzSSee4xxtptOvuueBRUdiiCDL-nghpkB0il1qbYIhcBSGfUKU_bjL3588piUWrTKZxPKeRnRirXftxJ5jB_vg5Vrb1tyzLEriAHlH2tCMos4Yh1v7bKilERVijEIctixNnNlLUvBiDOVsX-BfdyRO158SWrQ0P6yrPOhNbLxvMhY-Dp7L8gYsZBoFi1BnDSxJbEPvmuDMh28a"; - -using namespace Spotify_types; -void connect_to_wifi(); -//Client without Auth token -//Spotify sp(client_id, client_secret, port, true); -//Client with Auth token -Spotify sp(client_id, client_secret, refresh_token, true); -void setup() { - Serial.begin(115200); - connect_to_wifi(); - // Uncomment the following few lines to get the auth token - /*sp.begin(); - while(!sp.is_auth()){ - sp.handle_client(); - }*/ - print_response(sp.pause_playback()); -} - -void loop() { - -} -void connect_to_wifi(){ - WiFi.begin(ssid, password); - Serial.print("Connecting to WiFi..."); - while (WiFi.status() != WL_CONNECTED) { - delay(1000); - Serial.print("."); - } - Serial.println(); - Serial.println("Connected to WiFi"); -} -