mirror of
https://github.com/RSS-Bridge/rss-bridge.git
synced 2024-11-21 09:05:26 +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',
|
||||
'type' => 'text',
|
||||
'required' => true,
|
||||
'exampleValue' => 'spotify:artist:4lianjyuR1tqf6oUX8kjrZ [,spotify:playlist:37i9dQZF1DXcBWIGoYBM5M,spotify:show:6ShFMYxeDNMo15COLObDvC]',
|
||||
|
||||
// spotify:playlist:37i9dQZF1DXcBWIGoYBM5M
|
||||
// spotify:show:6ShFMYxeDNMo15COLObDvC
|
||||
'exampleValue' => 'spotify:artist:4lianjyuR1tqf6oUX8kjrZ',
|
||||
],
|
||||
'albumtype' => [
|
||||
'name' => 'Album type',
|
||||
|
@ -93,6 +96,25 @@ class SpotifyBridge extends BridgeAbstract
|
|||
private $token = '';
|
||||
|
||||
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();
|
||||
|
||||
|
@ -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()
|
||||
{
|
||||
$entries = [];
|
||||
|
@ -276,27 +319,6 @@ class SpotifyBridge extends BridgeAbstract
|
|||
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()
|
||||
{
|
||||
if (empty($this->uri)) {
|
||||
|
@ -346,4 +368,4 @@ class SpotifyBridge extends BridgeAbstract
|
|||
{
|
||||
return 'https://www.scdn.co/i/_global/favicon.png';
|
||||
}
|
||||
}
|
||||
}
|
|
@ -44,8 +44,8 @@ class CacheMiddleware implements Middleware
|
|||
$response = $next($request);
|
||||
|
||||
if (in_array($response->getCode(), [403, 429, 500, 503])) {
|
||||
// Cache these responses for about ~20 mins on average
|
||||
$this->cache->set($cacheKey, $response, 60 * 15 + rand(1, 60 * 10));
|
||||
// Cache these responses for about ~10 mins on average
|
||||
$this->cache->set($cacheKey, $response, 60 * 5 + rand(1, 60 * 10));
|
||||
}
|
||||
|
||||
// For 1% of requests, prune cache
|
||||
|
|
Loading…
Reference in a new issue