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.
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
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; }
}
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 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.
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);