mirror of
https://github.com/SoPat712/allstarr.git
synced 2026-02-09 23:55:10 -05:00
Fix GraphQL query for fetching user playlists - use libraryV3
- Changed from fetchLibraryPlaylists to libraryV3 operation (correct Spotify GraphQL endpoint) - Use GET request with query params instead of POST (matches Jellyfin plugin implementation) - Updated response parsing to match libraryV3 structure (me.libraryV3.items[].item.data) - Fixed owner field to use 'username' instead of 'name' - This should resolve the BadRequest (400) errors when fetching user playlists
This commit is contained in:
@@ -775,53 +775,18 @@ public class SpotifyApiClient : IDisposable
|
||||
|
||||
while (true)
|
||||
{
|
||||
// GraphQL query to fetch user playlists
|
||||
var graphqlQuery = new
|
||||
// GraphQL query to fetch user playlists - using libraryV3 operation
|
||||
var queryParams = new Dictionary<string, string>
|
||||
{
|
||||
operationName = "fetchLibraryPlaylists",
|
||||
variables = new
|
||||
{
|
||||
offset,
|
||||
limit
|
||||
},
|
||||
query = @"
|
||||
query fetchLibraryPlaylists($offset: Int!, $limit: Int!) {
|
||||
me {
|
||||
library {
|
||||
playlists(offset: $offset, limit: $limit) {
|
||||
totalCount
|
||||
items {
|
||||
playlist {
|
||||
uri
|
||||
name
|
||||
description
|
||||
images {
|
||||
url
|
||||
}
|
||||
ownerV2 {
|
||||
data {
|
||||
__typename
|
||||
... on User {
|
||||
id
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}"
|
||||
{ "operationName", "libraryV3" },
|
||||
{ "variables", $"{{\"filters\":[\"Playlists\",\"By Spotify\"],\"order\":null,\"textFilter\":\"\",\"features\":[\"LIKED_SONGS\",\"YOUR_EPISODES\"],\"offset\":{offset},\"limit\":{limit}}}" },
|
||||
{ "extensions", "{\"persistedQuery\":{\"version\":1,\"sha256Hash\":\"50650f72ea32a99b5b46240bee22fea83024eec302478a9a75cfd05a0814ba99\"}}" }
|
||||
};
|
||||
|
||||
var request = new HttpRequestMessage(HttpMethod.Post, $"{WebApiBase}/query")
|
||||
{
|
||||
Content = new StringContent(
|
||||
JsonSerializer.Serialize(graphqlQuery),
|
||||
System.Text.Encoding.UTF8,
|
||||
"application/json")
|
||||
};
|
||||
var queryString = string.Join("&", queryParams.Select(kv => $"{Uri.EscapeDataString(kv.Key)}={Uri.EscapeDataString(kv.Value)}"));
|
||||
var url = $"{WebApiBase}/query?{queryString}";
|
||||
|
||||
var request = new HttpRequestMessage(HttpMethod.Get, url);
|
||||
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
|
||||
var response = await _webApiClient.SendAsync(request, cancellationToken);
|
||||
@@ -849,20 +814,44 @@ public class SpotifyApiClient : IDisposable
|
||||
|
||||
if (!root.TryGetProperty("data", out var data) ||
|
||||
!data.TryGetProperty("me", out var me) ||
|
||||
!me.TryGetProperty("library", out var library) ||
|
||||
!library.TryGetProperty("playlists", out var playlistsData) ||
|
||||
!playlistsData.TryGetProperty("items", out var items))
|
||||
!me.TryGetProperty("libraryV3", out var library) ||
|
||||
!library.TryGetProperty("items", out var items))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// Get total count
|
||||
if (library.TryGetProperty("totalCount", out var totalCount))
|
||||
{
|
||||
var total = totalCount.GetInt32();
|
||||
if (total == 0) break;
|
||||
}
|
||||
|
||||
var itemCount = 0;
|
||||
foreach (var item in items.EnumerateArray())
|
||||
{
|
||||
itemCount++;
|
||||
|
||||
if (!item.TryGetProperty("playlist", out var playlist))
|
||||
if (!item.TryGetProperty("item", out var playlistItem) ||
|
||||
!playlistItem.TryGetProperty("data", out var playlist))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get playlist URI/ID
|
||||
string? uri = null;
|
||||
if (playlistItem.TryGetProperty("uri", out var uriProp))
|
||||
{
|
||||
uri = uriProp.GetString();
|
||||
}
|
||||
else if (playlistItem.TryGetProperty("_uri", out var uriProp2))
|
||||
{
|
||||
uri = uriProp2.GetString();
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(uri)) continue;
|
||||
|
||||
var spotifyId = uri.Replace("spotify:playlist:", "", StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
var itemName = playlist.TryGetProperty("name", out var n) ? n.GetString() ?? "" : "";
|
||||
|
||||
@@ -873,22 +862,19 @@ public class SpotifyApiClient : IDisposable
|
||||
continue;
|
||||
}
|
||||
|
||||
var uri = playlist.TryGetProperty("uri", out var u) ? u.GetString() ?? "" : "";
|
||||
var spotifyId = uri.Replace("spotify:playlist:", "", StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
// Get track count if available
|
||||
var trackCount = 0;
|
||||
if (playlist.TryGetProperty("content", out var content) &&
|
||||
content.TryGetProperty("totalCount", out var totalCount))
|
||||
content.TryGetProperty("totalCount", out var totalTrackCount))
|
||||
{
|
||||
trackCount = totalCount.GetInt32();
|
||||
trackCount = totalTrackCount.GetInt32();
|
||||
}
|
||||
|
||||
// Get owner name
|
||||
string? ownerName = null;
|
||||
if (playlist.TryGetProperty("ownerV2", out var ownerV2) &&
|
||||
ownerV2.TryGetProperty("data", out var ownerData) &&
|
||||
ownerData.TryGetProperty("name", out var ownerNameProp))
|
||||
ownerData.TryGetProperty("username", out var ownerNameProp))
|
||||
{
|
||||
ownerName = ownerNameProp.GetString();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user