Use client id & secret for Spotify

This commit is contained in:
philippe44
2025-12-25 00:02:02 +01:00
parent 1e3de24bdf
commit c0d2add55b
4 changed files with 41 additions and 56 deletions

View File

@@ -7,6 +7,7 @@
#include <vector> // for vector
#include "BellLogger.h" // for AbstractLogger
#include "BellUtils.h" // for BELL_SLEEP_MS
#include "CSpotContext.h" // for Context
#include "HTTPClient.h"
#include "Logger.h" // for CSPOT_LOG
@@ -24,13 +25,8 @@
#include "nlohmann/json_fwd.hpp" // for json
#endif
#include "protobuf/login5.pb.h" // for LoginRequest
using namespace cspot;
static std::string CLIENT_ID =
"65b708073fc0480ea92a077233ca87bd"; // Spotify web client's client id
static std::string SCOPES =
"streaming,user-library-read,user-library-modify,user-top-read,user-read-"
"recently-played"; // Required access scopes
@@ -68,69 +64,43 @@ void AccessKeyFetcher::updateAccessKey() {
keyPending = true;
// Prepare a protobuf login request
static LoginRequest loginRequest = LoginRequest_init_zero;
static LoginResponse loginResponse = LoginResponse_init_zero;
// Assign necessary request fields
loginRequest.client_info.client_id.funcs.encode = &bell::nanopb::encodeString;
loginRequest.client_info.client_id.arg = &CLIENT_ID;
loginRequest.client_info.device_id.funcs.encode = &bell::nanopb::encodeString;
loginRequest.client_info.device_id.arg = &ctx->config.deviceId;
loginRequest.login_method.stored_credential.username.funcs.encode =
&bell::nanopb::encodeString;
loginRequest.login_method.stored_credential.username.arg =
&ctx->config.username;
// Set login method to stored credential
loginRequest.which_login_method = LoginRequest_stored_credential_tag;
loginRequest.login_method.stored_credential.data.funcs.encode =
&bell::nanopb::encodeVector;
loginRequest.login_method.stored_credential.data.arg = &ctx->config.authData;
// Max retry of 3, can receive different hash cat types
int retryCount = 3;
bool success = false;
do {
auto encodedRequest = pbEncode(LoginRequest_fields, &loginRequest);
CSPOT_LOG(info, "Access token expired, fetching new one... %d",
encodedRequest.size());
CSPOT_LOG(info, "Access token expired, fetching new one...");
// Perform a login5 request, containing the encoded protobuf data
auto credentials = "grant_type=client_credentials&client_id=" + ctx->config.clientId + "&client_secret=" + ctx->config.clientSecret;
std::vector<uint8_t> body(credentials.begin(), credentials.end());
auto response = bell::HTTPClient::post(
"https://login5.spotify.com/v3/login",
{{"Content-Type", "application/x-protobuf"}}, encodedRequest);
auto responseBytes = response->bytes();
// Deserialize the response
pbDecode(loginResponse, LoginResponse_fields, responseBytes);
if (loginResponse.which_response == LoginResponse_ok_tag) {
// Successfully received an auth token
"https://accounts.spotify.com/api/token",
{ {"Content-Type", "application/x-www-form-urlencoded"} }, body);
#ifdef BELL_ONLY_CJSON
cJSON* root = cJSON_Parse(response->body().data());
if (!cJSON_GetObjectItem(root, "error")) {
accessKey = std::string(cJSON_GetObjectItem(root, "access_token")->valuestring);
int expiresIn = cJSON_GetObjectItem(root, "expires_in")->valueint;
cJSON_Delete(root);
#else
auto root = nlohmann::json::parse(response->bytes());
if (!root.contains("error")) {
accessKey = std::string(root["access_token"]);
int expiresIn = root["expires_in"];
#endif
// Successfully received an auth token
CSPOT_LOG(info, "Access token sucessfully fetched");
success = true;
accessKey = std::string(loginResponse.response.ok.access_token);
// Expire in ~30 minutes
int expiresIn = 3600 / 2;
if (loginResponse.response.ok.has_access_token_expires_in) {
int expiresIn = loginResponse.response.ok.access_token_expires_in / 2;
}
this->expiresAt =
ctx->timeProvider->getSyncedTimestamp() + (expiresIn * 1000);
} else {
CSPOT_LOG(error, "Failed to fetch access token");
ctx->timeProvider->getSyncedTimestamp() + (expiresIn * 1000);
}
else {
CSPOT_LOG(error, "Failed to fetch access token");
BELL_SLEEP_MS(3000);
}
// Free up allocated memory for response
pb_release(LoginResponse_fields, &loginResponse);
retryCount--;
} while (retryCount >= 0 && !success);