C# check if Twitch steam is online or not

Hello,
I am developing a C# application which is supposed to check whether a stream is online or not. Though, I am having difficulties in doing so. I know I have to use Twitch API to do it but can’t figure out how exactly.

https://api.twitch.tv/kraken/streams/camoduck?client_id=xskte44y2wfqin464ayecyc09nikcj

Before, you could use kraken but this doesn’t to seem to work anymore. Instead, I have to use helix and for that I believe the “client-id” needs to be passed as header in the url. But i don’t know how to do that exactly. Could someone help me with coming up with proper url. Thanks in advance

You should use HttpClient, for example:

class SomeClass {
        static HttpClientHandler hcHandle = new HttpClientHandler();

        static async Task<bool> IsOnline(string channel)
        {
            using (var hc = new HttpClient(hcHandle, false))
                    // false here prevents disposing the handler, which should live for the duration of the program and be shared by all requests that use the same handler properties
            {
                hc.DefaultRequestHeaders.Add("Client-ID", "your client id");
                hc.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", "your oauth token, should you have one (you should, but not required)");
                hc.DefaultRequestHeaders.UserAgent.ParseAdd("this would be good practice to set to your own");
                hc.Timeout = TimeSpan.FromSeconds(5); // good idea to set to something reasonable

                using (var response = await hc.GetAsync($"https://api.twitch.tv/helix/streams?user_login={channel}"))
                {
                    response.EnsureSuccessStatusCode(); // throws, if fails, can check response.StatusCode yourself if you prefer
                    string jsonString = await response.Content.ReadAsStringAsync();
                    // TODO: parse json and return true, if the returned array contains the stream
                }
            }
        }
}

Hello, Thanks for your response. would you be able to tell me if this is the correct way to finish it.

var r = JsonConvert.DeserializeObject<RootObject>(jsonString);
                    if (r.data[0] == null)
                    {
                        
                    }
                    else
                    {
                        return true;
                    }

After your code, this is what i added. I used json2csharp.com and got this:

public class Datum
{
    public string id { get; set; }
    public string user_id { get; set; }
    public string user_name { get; set; }
    public string game_id { get; set; }
    public string type { get; set; }
    public string title { get; set; }
    public int viewer_count { get; set; }
    public DateTime started_at { get; set; }
    public string language { get; set; }
    public string thumbnail_url { get; set; }
    public List<string> tag_ids { get; set; }
}

public class Pagination
{
    public string cursor { get; set; }
}

public class RootObject
{
    public List<Datum> data { get; set; }
    public Pagination pagination { get; set; }
}

Please let me know, appreciate your help

r.data[0] will throw index out of bounds. Instead: return !(r == default(RootObject) || r.data.Length == 0);

json2csharp gives a good base, but I’d recommend using tags and C#-style naming for the objects instead.

E.G.

public class Datum
{
    [JsonProperty("id")] public string ID { get; set; }
    [JsonProperty("user_id")] public string UserID { get; set; }
}

I’d also call RootObject something else like HelixStreamsResponse, so it’s immediately clear, and you don’t end up with multiple RootObjects for different requests.

Im a bit confused now. Firstly, do you mean to do this?

if (!(r == default(RootObject)))
                {
                    
                }
                else
                {
                    return true;
                }

im not sure why but using r.data.Length == 0) gives an error on Legnth:

|Error|CS1061|‘List’ does not contain a definition for ‘Length’ and no accessible extension method ‘Length’ accepting a first argument of type ‘List’ could be found (are you missing a using directive or an assembly reference?)

I can’t even seem to get the data such r.data.type or anything else:

|Error|CS1061|‘List’ does not contain a definition for ‘id’ and no accessible extension method ‘id’ accepting a first argument of type ‘List’ could be found (are you missing a using directive or an assembly reference?)

I have done what you told me to do:

 [JsonProperty("id")] public string ID { get; set; }
    [JsonProperty("userId")] public string user_id { get; set; }
    [JsonProperty("user_name")] public string user_name { get; set; }
    [JsonProperty("game_id")] public string game_id { get; set; }
    [JsonProperty("type")] public string type { get; set; }
    [JsonProperty("title")] public string title { get; set; }
    [JsonProperty("viewer_count")] public int viewer_count { get; set; }
    [JsonProperty("datetime")] public DateTime started_at { get; set; }
    [JsonProperty("language")] public string language { get; set; }
    [JsonProperty("thumb_url")] public string thumbnail_url { get; set; }
    [JsonProperty("tag_ids")] public List<string> tag_ids { get; set; }
}

public class Pagination
{
    public string cursor { get; set; }
}

public class RootObject
{
    public List<Datum> data { get; set; }
    public Pagination pagination { get; set; }
}

Doesn’t seem to work.

Here is rest of the code as well if you want to see.

static HttpClientHandler hcHandle = new HttpClientHandler();

    static async Task<bool> IsOnline(string channel)
    {
        using (var hc = new HttpClient(hcHandle, false))
        // false here prevents disposing the handler, which should live for the duration of the program and be shared by all requests that use the same handler properties
        {
            hc.DefaultRequestHeaders.Add("Client-ID", "51dn565kyrjdvphqwhxvi1agfgq3mn");
            //hc.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", "your oauth token, should you have one (you should, but not required)");
            //hc.DefaultRequestHeaders.UserAgent.ParseAdd("this would be good practice to set to your own");
            hc.Timeout = TimeSpan.FromSeconds(15); // good idea to set to something reasonable

            using (var response = await hc.GetAsync($"https://api.twitch.tv/helix/streams?user_login={channel}"))
            {
                response.EnsureSuccessStatusCode(); // throws, if fails, can check response.StatusCode yourself if you prefer
                string jsonString = await response.Content.ReadAsStringAsync();
                // TODO: parse json and return true, if the returned array contains the stream
                var r = JsonConvert.DeserializeObject<RootObject>(jsonString);

                if (!(r == default(RootObject)))
                {
                    
                }
                else
                {
                    return true;
                }

            }
        }
        return false;
    }
    

    public async void button1_Click(object sender, EventArgs e)
    {
        bool is_valid = await IsOnline("Tumblurr");
        if(is_valid == false)
        {
            MessageBox.Show("stream is offline");
        }
        else
        {
            MessageBox.Show("stream is online");
        }
       
    }

Really appreiciate your help. I’m pretty new to API and JSON things. So Thanks alot.

if (something)
{
  return false;
}
else
{
  return true;
}

can always be simplified as

return !something;

I meant .Count instead of .Length. Didn’t realize it was a list and not an array.

r == default(RootObject) // checks that r has something
r.data.Count == 0 // checks that there is a stream object in the response
r == default(RootObject) || r.data.Count == 0 // no response or response had no stream
!(r == default(RootObject) || r.data.Count == 0) // there is a response and that response contains a live stream
// so you want this for "the requested stream is live: true/false":
return !(r == default(RootObject) || r.data.Count == 0);

Thank you so much for all your help. That should clear everything. Really appreciate all of your help and your detailed answers!

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.