mirror of
https://github.com/RSS-Bridge/rss-bridge.git
synced 2025-02-18 16:19:55 +03:00
fix(spotify): detect rate limiting (#4253)
This commit is contained in:
parent
3dc8b65a0b
commit
293d04f296
2 changed files with 47 additions and 25 deletions
|
@ -37,7 +37,10 @@ class SpotifyBridge extends BridgeAbstract
|
||||||
'name' => 'Spotify URIs',
|
'name' => 'Spotify URIs',
|
||||||
'type' => 'text',
|
'type' => 'text',
|
||||||
'required' => true,
|
'required' => true,
|
||||||
'exampleValue' => 'spotify:artist:4lianjyuR1tqf6oUX8kjrZ [,spotify:playlist:37i9dQZF1DXcBWIGoYBM5M,spotify:show:6ShFMYxeDNMo15COLObDvC]',
|
|
||||||
|
// spotify:playlist:37i9dQZF1DXcBWIGoYBM5M
|
||||||
|
// spotify:show:6ShFMYxeDNMo15COLObDvC
|
||||||
|
'exampleValue' => 'spotify:artist:4lianjyuR1tqf6oUX8kjrZ',
|
||||||
],
|
],
|
||||||
'albumtype' => [
|
'albumtype' => [
|
||||||
'name' => 'Album type',
|
'name' => 'Album type',
|
||||||
|
@ -93,6 +96,25 @@ class SpotifyBridge extends BridgeAbstract
|
||||||
private $token = '';
|
private $token = '';
|
||||||
|
|
||||||
public function collectData()
|
public function collectData()
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* https://developer.spotify.com/documentation/web-api/concepts/rate-limits
|
||||||
|
*/
|
||||||
|
$cacheKey = 'spotify_rate_limit';
|
||||||
|
|
||||||
|
try {
|
||||||
|
$this->collectDataInternal();
|
||||||
|
} catch (HttpException $e) {
|
||||||
|
if ($e->getCode() === 429) {
|
||||||
|
$retryAfter = $e->response->getHeader('Retry-After') ?? (60 * 5);
|
||||||
|
$this->cache->set($cacheKey, true, $retryAfter);
|
||||||
|
throw new RateLimitException(sprintf('Rate limited by spotify, try again in %s seconds', $retryAfter));
|
||||||
|
}
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function collectDataInternal()
|
||||||
{
|
{
|
||||||
$this->fetchAccessToken();
|
$this->fetchAccessToken();
|
||||||
|
|
||||||
|
@ -125,6 +147,27 @@ class SpotifyBridge extends BridgeAbstract
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function fetchAccessToken()
|
||||||
|
{
|
||||||
|
$cacheKey = sprintf('SpotifyBridge:%s:%s', $this->getInput('clientid'), $this->getInput('clientsecret'));
|
||||||
|
|
||||||
|
$token = $this->cache->get($cacheKey);
|
||||||
|
if ($token) {
|
||||||
|
$this->token = $token;
|
||||||
|
} else {
|
||||||
|
$basicAuth = base64_encode(sprintf('%s:%s', $this->getInput('clientid'), $this->getInput('clientsecret')));
|
||||||
|
$json = getContents('https://accounts.spotify.com/api/token', [
|
||||||
|
"Authorization: Basic $basicAuth",
|
||||||
|
], [
|
||||||
|
CURLOPT_POSTFIELDS => 'grant_type=client_credentials',
|
||||||
|
]);
|
||||||
|
$data = Json::decode($json);
|
||||||
|
$this->token = $data['access_token'];
|
||||||
|
|
||||||
|
$this->cache->set($cacheKey, $this->token, 3600);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private function getEntriesFromQuery()
|
private function getEntriesFromQuery()
|
||||||
{
|
{
|
||||||
$entries = [];
|
$entries = [];
|
||||||
|
@ -276,27 +319,6 @@ class SpotifyBridge extends BridgeAbstract
|
||||||
return DateTime::createFromFormat('Y-m-d', $date)->getTimestamp();
|
return DateTime::createFromFormat('Y-m-d', $date)->getTimestamp();
|
||||||
}
|
}
|
||||||
|
|
||||||
private function fetchAccessToken()
|
|
||||||
{
|
|
||||||
$cacheKey = sprintf('SpotifyBridge:%s:%s', $this->getInput('clientid'), $this->getInput('clientsecret'));
|
|
||||||
|
|
||||||
$token = $this->cache->get($cacheKey);
|
|
||||||
if ($token) {
|
|
||||||
$this->token = $token;
|
|
||||||
} else {
|
|
||||||
$basicAuth = base64_encode(sprintf('%s:%s', $this->getInput('clientid'), $this->getInput('clientsecret')));
|
|
||||||
$json = getContents('https://accounts.spotify.com/api/token', [
|
|
||||||
"Authorization: Basic $basicAuth",
|
|
||||||
], [
|
|
||||||
CURLOPT_POSTFIELDS => 'grant_type=client_credentials',
|
|
||||||
]);
|
|
||||||
$data = Json::decode($json);
|
|
||||||
$this->token = $data['access_token'];
|
|
||||||
|
|
||||||
$this->cache->set($cacheKey, $this->token, 3600);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getURI()
|
public function getURI()
|
||||||
{
|
{
|
||||||
if (empty($this->uri)) {
|
if (empty($this->uri)) {
|
||||||
|
|
|
@ -44,8 +44,8 @@ class CacheMiddleware implements Middleware
|
||||||
$response = $next($request);
|
$response = $next($request);
|
||||||
|
|
||||||
if (in_array($response->getCode(), [403, 429, 500, 503])) {
|
if (in_array($response->getCode(), [403, 429, 500, 503])) {
|
||||||
// Cache these responses for about ~20 mins on average
|
// Cache these responses for about ~10 mins on average
|
||||||
$this->cache->set($cacheKey, $response, 60 * 15 + rand(1, 60 * 10));
|
$this->cache->set($cacheKey, $response, 60 * 5 + rand(1, 60 * 10));
|
||||||
}
|
}
|
||||||
|
|
||||||
// For 1% of requests, prune cache
|
// For 1% of requests, prune cache
|
||||||
|
|
Loading…
Add table
Reference in a new issue