/// <summary>
        /// Asynchronously search the Spotify catalog using a keyword string.
        /// </summary>
        /// <param name="query">
        /// A <see cref="string"/> representing the keywords to search with.
        /// This can contain optional field filters and operators. Information about how to use these can be found in
        /// the <see href="https://spotify.dev/documentation/web-api/reference/search/search/">Spotify Developer documentation</see>.
        /// </param>
        /// <param name="types">The <see cref="SearchResultTypes"/> to include in the search.</param>
        /// <param name="market">
        /// An optional <see cref="CountryCode"/> to limit returned content to a certain market.
        /// Playlists are not affected by this parameter.
        /// <see cref="CountryCode.FromToken"/> can be used if the access token used is a valid user access token.
        /// </param>
        /// <param name="limit">
        /// The maximum number of results to return.
        /// This limit is applied within each type, not on the total response.
        /// </param>
        /// <param name="offset">The index of the first result to return.</param>
        /// <param name="includeExternal">Whether or not to include any relevant audio content that is hosted externally.</param>
        /// <param name="accessTokenProvider">An optional <see cref="IAccessTokenProvider"/> to use instead of the default.</param>
        /// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests.</param>
        /// <returns>A <see cref="Task{TResult}"/> representing the asynchronous operation.</returns>
        public Task <SearchResult> SearchAsync(
            string query,
            SearchResultTypes types,
            CountryCode?market   = null,
            int?limit            = null,
            int?offset           = null,
            bool?includeExternal = null,
            IAccessTokenProvider?accessTokenProvider = null,
            CancellationToken cancellationToken      = default)
        {
            var uriBuilder = new SpotifyUriBuilder($"{BaseUrl}/search")
                             .AppendToQuery("query", query.Replace(" ", "%20"))
                             .AppendJoinToQuery("type", ',', types.GetFlags().Select(value => value.GetName().ToLower()))
                             .AppendToQueryIfNotNull("market", market?.ToSpotifyString())
                             .AppendToQueryIfNotNull("limit", limit)
                             .AppendToQueryIfNotNull("offset", offset)
                             .AppendToQueryIfNotNull("include_external", includeExternal);

            return(SendAsync <SearchResult>(
                       uriBuilder.Build(),
                       HttpMethod.Get,
                       content: null,
                       accessTokenProvider,
                       cancellationToken));
        }
Example #2
0
        public Task SaveShowsAsync(
            IEnumerable <string> ids,
            IAccessTokenProvider?accessTokenProvider = null,
            CancellationToken cancellationToken      = default)
        {
            var uriBuilder = new SpotifyUriBuilder($"{BaseUrl}/me/shows")
                             .AppendJoinToQuery("ids", ',', ids);

            return(SendAsync(
                       uriBuilder.Build(),
                       HttpMethod.Put,
                       content: null,
                       accessTokenProvider,
                       cancellationToken));
        }
        public Task <IReadOnlyList <AudioFeatures> > GetAudioFeaturesForTracksAsync(
            IEnumerable <string> ids,
            IAccessTokenProvider?accessTokenProvider = null,
            CancellationToken cancellationToken      = default)
        {
            var uriBuilder = new SpotifyUriBuilder($"{BaseUrl}/audio-features")
                             .AppendJoinToQuery("ids", ',', ids);

            return(SendAsync <IReadOnlyList <AudioFeatures> >(
                       uriBuilder.Build(),
                       HttpMethod.Get,
                       content: null,
                       accessTokenProvider,
                       cancellationToken));
        }
Example #4
0
        public Task <IReadOnlyList <bool> > CheckCurrentUserFollowsUsersAsync(
            IEnumerable <string> ids,
            IAccessTokenProvider?accessTokenProvider = null,
            CancellationToken cancellationToken      = default)
        {
            var uriBuilder = new SpotifyUriBuilder($"{BaseUrl}/me/following/contains")
                             .AppendToQuery("type", "user")
                             .AppendJoinToQuery("ids", ',', ids);

            return(SendAsync <IReadOnlyList <bool> >(
                       uriBuilder.Build(),
                       HttpMethod.Get,
                       content: null,
                       accessTokenProvider,
                       cancellationToken));
        }
Example #5
0
        public Task <IReadOnlyList <bool> > CheckUsersFollowPlaylistAsync(
            string id,
            IEnumerable <string> userIds,
            IAccessTokenProvider?accessTokenProvider = null,
            CancellationToken cancellationToken      = default)
        {
            var uriBuilder = new SpotifyUriBuilder($"{BaseUrl}/playlists/{id}/followers/contains")
                             .AppendJoinToQuery("ids", ',', userIds);

            return(SendAsync <IReadOnlyList <bool> >(
                       uriBuilder.Build(),
                       HttpMethod.Get,
                       content: null,
                       accessTokenProvider,
                       cancellationToken));
        }
        /// <summary>
        /// Asynchronously get the top tracks of an <see cref="Artist"/> from the Spotify catalog.
        /// </summary>
        /// <param name="id">
        /// A <see cref="string"/> representing the Spotify ID of the <see cref="Artist"/> to get the top tracks of.
        /// </param>
        /// <param name="market">A <see cref="CountryCode"/> representing the market to get the top tracks for.</param>
        /// <param name="accessTokenProvider">An optional <see cref="IAccessTokenProvider"/> to use instead of the default.</param>
        /// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests.</param>
        /// <returns>A <see cref="Task{TResult}"/> representing the asynchronous operation.</returns>
        public Task <IReadOnlyList <Track> > GetArtistTopTracksAsync(
            string id,
            CountryCode market,
            IAccessTokenProvider?accessTokenProvider = null,
            CancellationToken cancellationToken      = default)
        {
            var uriBuilder = new SpotifyUriBuilder($"{BaseUrl}/artists/{id}/top-tracks")
                             .AppendToQuery("country", market);

            return(SendAsync <IReadOnlyList <Track> >(
                       uriBuilder.Build(),
                       HttpMethod.Get,
                       content: null,
                       accessTokenProvider,
                       cancellationToken));
        }
Example #7
0
        private Task <IReadOnlyList <bool> > CheckAsync(
            string objectType,
            IEnumerable <string> ids,
            IAccessTokenProvider?accessTokenProvider = null,
            CancellationToken cancellationToken      = default)
        {
            var uriBuilder = new SpotifyUriBuilder($"{BaseUrl}/me/{objectType}s/contains")
                             .AppendJoinToQuery("ids", ',', ids);

            return(SendAsync <IReadOnlyList <bool> >(
                       uriBuilder.Build(),
                       HttpMethod.Get,
                       content: null,
                       accessTokenProvider,
                       cancellationToken));
        }
        /// <summary>
        /// Asynchronously get an <see cref="Album"/> from the Spotify catalog.
        /// </summary>
        /// <param name="id">A <see cref="string"/> representing the Spotify ID of the <see cref="Album"/> to get.</param>
        /// <param name="market">
        /// An optional <see cref="CountryCode"/> to apply
        /// <see href="https://spotify.dev/documentation/general/guides/track-relinking-guide/">track relinking</see>.
        /// </param>
        /// <param name="accessTokenProvider">An optional <see cref="IAccessTokenProvider"/> to use instead of the default.</param>
        /// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests.</param>
        /// <returns>A <see cref="Task{TResult}"/> representing the asynchronous operation.</returns>
        public Task <Album> GetAlbumAsync(
            string id,
            CountryCode?market = null,
            IAccessTokenProvider?accessTokenProvider = null,
            CancellationToken cancellationToken      = default)
        {
            var uriBuilder = new SpotifyUriBuilder($"{BaseUrl}/albums/{id}")
                             .AppendToQueryIfNotNull("market", market?.ToSpotifyString());

            return(SendAsync <Album>(
                       uriBuilder.Build(),
                       HttpMethod.Get,
                       content: null,
                       accessTokenProvider,
                       cancellationToken));
        }
Example #9
0
        public Task ReplacePlaylistItemsAsync(
            string id,
            IEnumerable <string> uris,
            IAccessTokenProvider?accessTokenProvider = null,
            CancellationToken cancellationToken      = default)
        {
            var uriBuilder = new SpotifyUriBuilder($"{BaseUrl}/playlists/{id}/tracks")
                             .AppendJoinToQuery("uris", ',', uris);

            return(SendAsync(
                       uriBuilder.Build(),
                       HttpMethod.Put,
                       content: null,
                       accessTokenProvider,
                       cancellationToken));
        }
        /// <summary>
        /// Asynchronously get multiple <see cref="Album"/> objects from the Spotify catalog.
        /// </summary>
        /// <param name="ids">
        /// An <see cref="IEnumerable{T}"/> of <see cref="string"/> objects
        /// representing the Spotify IDs of the <see cref="Album"/> objects to get.
        /// </param>
        /// <param name="market">
        /// An optional <see cref="CountryCode"/> to apply
        /// <see href="https://spotify.dev/documentation/general/guides/track-relinking-guide/">track relinking</see>.
        /// </param>
        /// <param name="accessTokenProvider">An optional <see cref="IAccessTokenProvider"/> to use instead of the default.</param>
        /// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests.</param>
        /// <returns>A <see cref="Task{TResult}"/> representing the asynchronous operation.</returns>
        public Task <IReadOnlyList <Album?> > GetAlbumsAsync(
            IEnumerable <string> ids,
            CountryCode?market = null,
            IAccessTokenProvider?accessTokenProvider = null,
            CancellationToken cancellationToken      = default)
        {
            var uriBuilder = new SpotifyUriBuilder($"{BaseUrl}/albums")
                             .AppendJoinToQuery("ids", ',', ids)
                             .AppendToQueryIfNotNull("market", market?.ToSpotifyString());

            return(SendAsync <IReadOnlyList <Album?> >(
                       uriBuilder.Build(),
                       HttpMethod.Get,
                       content: null,
                       accessTokenProvider,
                       cancellationToken));
        }
Example #11
0
        public Task <Paging <Saved <Show> > > GetSavedShowsAsync(
            int?limit  = null,
            int?offset = null,
            IAccessTokenProvider?accessTokenProvider = null,
            CancellationToken cancellationToken      = default)
        {
            var uriBuilder = new SpotifyUriBuilder($"{BaseUrl}/me/shows")
                             .AppendToQueryIfNotNull("limit", limit)
                             .AppendToQueryIfNotNull("offset", offset);

            return(SendAsync <Paging <Saved <Show> > >(
                       uriBuilder.Build(),
                       HttpMethod.Get,
                       content: null,
                       accessTokenProvider,
                       cancellationToken));
        }
Example #12
0
        public Task RemoveShowsAsync(
            IEnumerable <string> ids,
            CountryCode?market = null,
            IAccessTokenProvider?accessTokenProvider = null,
            CancellationToken cancellationToken      = default)
        {
            var uriBuilder = new SpotifyUriBuilder($"{BaseUrl}/me/shows")
                             .AppendJoinToQuery("ids", ',', ids)
                             .AppendToQueryIfNotNull("market", market?.ToSpotifyString());

            return(SendAsync(
                       uriBuilder.Build(),
                       HttpMethod.Delete,
                       content: null,
                       accessTokenProvider,
                       cancellationToken));
        }
Example #13
0
        public Task <Playlist> GetPlaylistAsync(
            string id,
            CountryCode?market = null,
            IAccessTokenProvider?accessTokenProvider = null,
            CancellationToken cancellationToken      = default)
        {
            var uriBuilder = new SpotifyUriBuilder($"{BaseUrl}/playlists/{id}")
                             .AppendToQueryIfNotNull("market", market)
                             .AppendToQuery("additional_types", "episode");

            return(SendAsync <Playlist>(
                       uriBuilder.Build(),
                       HttpMethod.Get,
                       content: null,
                       accessTokenProvider,
                       cancellationToken));
        }
Example #14
0
        public Task <Category> GetCategoryAsync(
            string id,
            CountryCode?country = null,
            string?locale       = null,
            IAccessTokenProvider?accessTokenProvider = null,
            CancellationToken cancellationToken      = default)
        {
            var uriBuilder = new SpotifyUriBuilder($"{BaseUrl}/browse/categories/{id}")
                             .AppendToQueryIfNotNull("country", country?.ToSpotifyString())
                             .AppendToQueryIfNotNull("locale", locale);

            return(SendAsync <Category>(
                       uriBuilder.Build(),
                       HttpMethod.Get,
                       content: null,
                       accessTokenProvider,
                       cancellationToken));
        }
Example #15
0
        private Task EditFollowing(
            string type,
            HttpMethod method,
            IEnumerable <string> ids,
            IAccessTokenProvider?accessTokenProvider,
            CancellationToken cancellationToken)
        {
            var uriBuilder = new SpotifyUriBuilder($"{BaseUrl}/me/following")
                             .AppendToQuery("type", type)
                             .AppendJoinToQuery("ids", ',', ids);

            return(SendAsync(
                       uriBuilder.Build(),
                       method,
                       content: null,
                       accessTokenProvider,
                       cancellationToken));
        }
Example #16
0
        public Task <Paging <SimplifiedPlaylist> > GetUserPlaylistsAsync(
            string userId,
            int?limit  = null,
            int?offset = null,
            IAccessTokenProvider?accessTokenProvider = null,
            CancellationToken cancellationToken      = default)
        {
            var uriBuilder = new SpotifyUriBuilder($"{BaseUrl}/users/{userId}/playlists")
                             .AppendToQueryIfNotNull("limit", limit)
                             .AppendToQueryIfNotNull("offset", offset);

            return(SendAsync <Paging <SimplifiedPlaylist> >(
                       uriBuilder.Build(),
                       HttpMethod.Get,
                       content: null,
                       accessTokenProvider,
                       cancellationToken));
        }
Example #17
0
        public Task <string> AddItemsToPlaylistAsync(
            string id,
            IEnumerable <string> uris,
            int?position = null,
            IAccessTokenProvider?accessTokenProvider = null,
            CancellationToken cancellationToken      = default)
        {
            var uriBuilder = new SpotifyUriBuilder($"{BaseUrl}/playlists/{id}")
                             .AppendJoinToQuery("uris", ',', uris)
                             .AppendToQueryIfNotNull("position", position);

            // TODO: Find a way to make this deserialize a SnapshotId object.
            return(SendAsync <string>(
                       uriBuilder.Build(),
                       HttpMethod.Post,
                       content: null,
                       accessTokenProvider,
                       cancellationToken));
        }
        public Task <Paging <Track> > GetTopTracksForCurrentUserAsync(
            int?limit           = null,
            int?offset          = null,
            TimeRange?timeRange = null,
            IAccessTokenProvider?accessTokenProvider = null,
            CancellationToken cancellationToken      = default)
        {
            var uriBuilder = new SpotifyUriBuilder($"{BaseUrl}/me/top/tracks")
                             .AppendToQueryIfNotNull("limit", limit)
                             .AppendToQueryIfNotNull("offset", offset)
                             .AppendToQueryIfNotNull("time_range", timeRange?.ToSpotifyString());

            return(SendAsync <Paging <Track> >(
                       uriBuilder.Build(),
                       HttpMethod.Get,
                       content: null,
                       accessTokenProvider,
                       cancellationToken));
        }
Example #19
0
        public Task <Paging <SimplifiedPlaylist> > GetCategoryPlaylistsAsync(
            string id,
            CountryCode?country = null,
            int?limit           = null,
            int?offset          = null,
            IAccessTokenProvider?accessTokenProvider = null,
            CancellationToken cancellationToken      = default)
        {
            var uriBuilder = new SpotifyUriBuilder($"{BaseUrl}/browse/categories/{id}/playlists")
                             .AppendToQueryIfNotNull("country", country?.ToSpotifyString())
                             .AppendToQueryIfNotNull("limit", limit)
                             .AppendToQueryIfNotNull("offset", offset);

            return(SendAsync <Paging <SimplifiedPlaylist> >(
                       uriBuilder.Build(),
                       HttpMethod.Get,
                       content: null,
                       accessTokenProvider,
                       cancellationToken));
        }
        /// <summary>
        /// Asynchronously get the tracks of an <see cref="Album"/> from the Spotify catalog.
        /// </summary>
        /// <param name="id">A <see cref="string"/> representing the Spotify ID of the <see cref="Album"/> to get the tracks of.</param>
        /// <param name="limit">The maximum number of results to return.</param>
        /// <param name="offset">The index of the first result to return.</param>
        /// <param name="market">
        /// An optional <see cref="CountryCode"/> to apply
        /// <see href="https://spotify.dev/documentation/general/guides/track-relinking-guide/">track relinking</see>.
        /// </param>
        /// <param name="accessTokenProvider">An optional <see cref="IAccessTokenProvider"/> to use instead of the default.</param>
        /// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests.</param>
        /// <returns>A <see cref="Task{TResult}"/> representing the asynchronous operation.</returns>
        public Task <Paging <SimplifiedTrack> > GetAlbumTracksAsync(
            string id,
            int?limit          = null,
            int?offset         = null,
            CountryCode?market = null,
            IAccessTokenProvider?accessTokenProvider = null,
            CancellationToken cancellationToken      = default)
        {
            var uriBuilder = new SpotifyUriBuilder($"{BaseUrl}/albums/{id}/tracks")
                             .AppendToQueryIfNotNull("limit", limit)
                             .AppendToQueryIfNotNull("offset", offset)
                             .AppendToQueryIfNotNull("market", market?.ToSpotifyString());

            return(SendAsync <Paging <SimplifiedTrack> >(
                       uriBuilder.Build(),
                       HttpMethod.Get,
                       content: null,
                       accessTokenProvider,
                       cancellationToken));
        }
Example #21
0
        private Task <Paging <TObject> > GetAsync <TObject>(
            string objectType,
            int?limit,
            int?offset,
            CountryCode?market,
            IAccessTokenProvider?accessTokenProvider,
            CancellationToken cancellationToken)
        {
            var uriBuilder = new SpotifyUriBuilder($"{BaseUrl}/me/{objectType}s")
                             .AppendToQueryIfNotNull("limit", limit)
                             .AppendToQueryIfNotNull("offset", offset)
                             .AppendToQueryIfNotNull("market", market?.ToSpotifyString());

            return(SendAsync <Paging <TObject> >(
                       uriBuilder.Build(),
                       HttpMethod.Get,
                       content: null,
                       accessTokenProvider,
                       cancellationToken));
        }
        /// <summary>
        /// Asynchronously get the albums of an <see cref="Artist"/> from the Spotify catalog.
        /// </summary>
        /// <param name="id">A <see cref="string"/> representing the Spotify ID of the <see cref="Artist"/> to get the albums of.</param>
        /// <param name="includeGroups">The <see cref="AlbumGroups"/> that the result should be filtered to include.</param>
        /// <param name="market">An optional <see cref="CountryCode"/> to limit the result to one particular geographical market.</param>
        /// <param name="limit">The maximum number of results to return.</param>
        /// <param name="offset">The index of the first result to return.</param>
        /// <param name="accessTokenProvider">An optional <see cref="IAccessTokenProvider"/> to use instead of the default.</param>
        /// <param name="cancellationToken">The <see cref="CancellationToken"/> to monitor for cancellation requests.</param>
        /// <returns>A <see cref="Task{TResult}"/> representing the asynchronous operation.</returns>
        public Task <Paging <SimplifiedAlbum> > GetArtistAlbumsAsync(
            string id,
            AlbumGroups?includeGroups = null,
            CountryCode?market        = null,
            int?limit  = null,
            int?offset = null,
            IAccessTokenProvider?accessTokenProvider = null,
            CancellationToken cancellationToken      = default)
        {
            var uriBuilder = new SpotifyUriBuilder($"{BaseUrl}/artists/{id}/albums")
                             .AppendJoinToQueryIfNotNull("include_groups", ',', includeGroups?.ToSpotifyStrings())
                             .AppendToQueryIfNotNull("market", market?.ToSpotifyString())
                             .AppendToQueryIfNotNull("limit", limit)
                             .AppendToQueryIfNotNull("offset", offset);

            return(SendAsync <Paging <SimplifiedAlbum> >(
                       uriBuilder.Build(),
                       HttpMethod.Get,
                       content: null,
                       accessTokenProvider,
                       cancellationToken));
        }