Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to call the Spotify API from C#

I'm trying to call the spotify API with C#. Unfortunately, I'm already stuck with getting the access token

This is how I tried to get it:

private static async Task<string> GetAccessToken()
        {
            SpotifyToken token = new SpotifyToken();

            string postString = string.Format("grant_type=client_credentials");
            byte[] byteArray = Encoding.UTF8.GetBytes(postString);

            string url = "https://accounts.spotify.com/api/token";

            WebRequest request = WebRequest.Create(url);
            request.Method = "POST";
            request.Headers.Add("Authorization", "Basic {Encoded myClientIdXXX:myAppSecretYYY}");
            request.ContentType = "application/x-www-form-urlencoded";
            request.ContentLength = byteArray.Length;
            using (Stream dataStream = request.GetRequestStream())
            {
                dataStream.Write(byteArray, 0, byteArray.Length);
                using (WebResponse response = await request.GetResponseAsync())
                {
                    using (Stream responseStream = response.GetResponseStream())
                    {
                        using (StreamReader reader = new StreamReader(responseStream))
                        {
                            string responseFromServer = reader.ReadToEnd();
                            token = JsonConvert.DeserializeObject<SpotifyToken>(responseFromServer);
                        }
                    }
                }
            }
            return token.access_token;
        }

But I get an error:

Der Remoteserver hat einen Fehler zurückgegeben: (400) Ungültige Anforderung.

Which translates to:

The remote server returned an error: (400) Bad Request.

What am I doing wrong here? I've registered my app at spotify and set the clientId and secret in the request header...

Thanks in advance

like image 689
Harry Avatar asked Nov 30 '15 20:11

Harry


2 Answers

Spotify API from C#

public string GetAccessToken()
    {
            SpotifyToken token = new SpotifyToken();
            string url5 = "https://accounts.spotify.com/api/token";
            var clientid = "your_client_id";
            var clientsecret = "your_client_secret";

            //request to get the access token
            var encode_clientid_clientsecret = Convert.ToBase64String(Encoding.UTF8.GetBytes(string.Format("{0}:{1}", clientid, clientsecret)));

            HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url5);

            webRequest.Method = "POST";
            webRequest.ContentType = "application/x-www-form-urlencoded";
            webRequest.Accept = "application/json";
            webRequest.Headers.Add("Authorization: Basic " + encode_clientid_clientsecret);

            var request = ("grant_type=client_credentials");
            byte[] req_bytes = Encoding.ASCII.GetBytes(request);
            webRequest.ContentLength = req_bytes.Length;

            Stream strm = webRequest.GetRequestStream();
            strm.Write(req_bytes, 0, req_bytes.Length);
            strm.Close();

            HttpWebResponse resp = (HttpWebResponse)webRequest.GetResponse();
            String json = "";
            using (Stream respStr = resp.GetResponseStream())
            {
                using (StreamReader rdr = new StreamReader(respStr, Encoding.UTF8))
                {
                    //should get back a string i can then turn to json and parse for accesstoken
                    json = rdr.ReadToEnd();
                    rdr.Close();
                }
            }
     return token.access_token;
}
like image 85
Ritesh Prajapti Avatar answered Nov 02 '22 23:11

Ritesh Prajapti


Do you really need to write your own client from scratch building WebRequests, etc.? Why not use an existing client like SpotifyAPI-NET?

Anyway, you can see how they do it, on GitHub:

https://github.com/JohnnyCrazy/SpotifyAPI-NET/blob/master/SpotifyAPI/Web/Auth/AutorizationCodeAuth.cs

using Newtonsoft.Json;
using SpotifyAPI.Web.Enums;
using SpotifyAPI.Web.Models;
using System;
using System.Collections.Specialized;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Text;
using System.Threading;

namespace SpotifyAPI.Web.Auth
{
    public class AutorizationCodeAuth
    {
        public delegate void OnResponseReceived(AutorizationCodeAuthResponse response);

        private SimpleHttpServer _httpServer;
        private Thread _httpThread;
        public String ClientId { get; set; }
        public String RedirectUri { get; set; }
        public String State { get; set; }
        public Scope Scope { get; set; }
        public Boolean ShowDialog { get; set; }

        /// <summary>
        ///     Will be fired once the user authenticated
        /// </summary>
        public event OnResponseReceived OnResponseReceivedEvent;

        /// <summary>
        ///     Start the auth process (Make sure the internal HTTP-Server ist started)
        /// </summary>
        public void DoAuth()
        {
            String uri = GetUri();
            Process.Start(uri);
        }

        /// <summary>
        ///     Refreshes auth by providing the clientsecret (Don't use this if you're on a client)
        /// </summary>
        /// <param name="refreshToken">The refresh-token of the earlier gathered token</param>
        /// <param name="clientSecret">Your Client-Secret, don't provide it if this is running on a client!</param>
        public Token RefreshToken(string refreshToken, string clientSecret)
        {
            using (WebClient wc = new WebClient())
            {
                wc.Proxy = null;
                wc.Headers.Add("Authorization",
                    "Basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes(ClientId + ":" + clientSecret)));
                NameValueCollection col = new NameValueCollection
                {
                    {"grant_type", "refresh_token"},
                    {"refresh_token", refreshToken}
                };

                String response;
                try
                {
                    byte[] data = wc.UploadValues("https://accounts.spotify.com/api/token", "POST", col);
                    response = Encoding.UTF8.GetString(data);
                }
                catch (WebException e)
                {
                    using (StreamReader reader = new StreamReader(e.Response.GetResponseStream()))
                    {
                        response = reader.ReadToEnd();
                    }
                }
                return JsonConvert.DeserializeObject<Token>(response);
            }
        }

        private String GetUri()
        {
            StringBuilder builder = new StringBuilder("https://accounts.spotify.com/authorize/?");
            builder.Append("client_id=" + ClientId);
            builder.Append("&response_type=code");
            builder.Append("&redirect_uri=" + RedirectUri);
            builder.Append("&state=" + State);
            builder.Append("&scope=" + Scope.GetStringAttribute(" "));
            builder.Append("&show_dialog=" + ShowDialog);
            return builder.ToString();
        }

        /// <summary>
        ///     Start the internal HTTP-Server
        /// </summary>
        public void StartHttpServer(int port = 80)
        {
            _httpServer = new SimpleHttpServer(port, AuthType.Authorization);
            _httpServer.OnAuth += HttpServerOnOnAuth;

            _httpThread = new Thread(_httpServer.Listen);
            _httpThread.Start();
        }

        private void HttpServerOnOnAuth(AuthEventArgs e)
        {
            OnResponseReceivedEvent?.Invoke(new AutorizationCodeAuthResponse()
            {
                Code = e.Code,
                State = e.State,
                Error = e.Error
            });
        }

        /// <summary>
        ///     This will stop the internal HTTP-Server (Should be called after you got the Token)
        /// </summary>
        public void StopHttpServer()
        {
            _httpServer = null;
        }

        /// <summary>
        ///     Exchange a code for a Token (Don't use this if you're on a client)
        /// </summary>
        /// <param name="code">The gathered code from the response</param>
        /// <param name="clientSecret">Your Client-Secret, don't provide it if this is running on a client!</param>
        /// <returns></returns>
        public Token ExchangeAuthCode(String code, String clientSecret)
        {
            using (WebClient wc = new WebClient())
            {
                wc.Proxy = null;

                NameValueCollection col = new NameValueCollection
                {
                    {"grant_type", "authorization_code"},
                    {"code", code},
                    {"redirect_uri", RedirectUri},
                    {"client_id", ClientId},
                    {"client_secret", clientSecret}
                };

                String response;
                try
                {
                    byte[] data = wc.UploadValues("https://accounts.spotify.com/api/token", "POST", col);
                    response = Encoding.UTF8.GetString(data);
                }
                catch (WebException e)
                {
                    using (StreamReader reader = new StreamReader(e.Response.GetResponseStream()))
                    {
                        response = reader.ReadToEnd();
                    }
                }
                return JsonConvert.DeserializeObject<Token>(response);
            }
        }
    }

    public struct AutorizationCodeAuthResponse
    {
        public String Code { get; set; }
        public String State { get; set; }
        public String Error { get; set; }
    }
}
like image 24
C. Augusto Proiete Avatar answered Nov 03 '22 00:11

C. Augusto Proiete