List of active streams using PHP & Twitch API

hello, guys. i have a problem with twitch api. i have an array of channels and i need to show on my site ONLY channels with online translations. what am i doing wrong? can someone help me with it?

<?php
$names[] = "xxxxxx";
$names[] = "xxxxxx";

foreach ($names as $channel) {
$request_params = array(
    'client_id' => 'xxxxxxxxx'
);
$params = http_build_query($request_params);
$result = json_decode(file_get_contents('https://api.twitch.tv/helix/streams/'. $channel . '/?'. $params));

$game_ID = $result -> stream -> id; 
$stream_name = $result -> stream -> game; 
$stream_status = $result -> stream -> channel -> status; 
$url_channel = $result -> stream -> channel -> url; 
$img_preview = $result -> stream -> preview -> template; 

if ($result -> stream == null) {
    echo 'channel offline!';
}
else {
    echo '<iframe src="https://player.twitch.tv/?channel=' . $channel . '" frameborder="0" allowfullscreen="true" scrolling="no" height="378" width="620"></iframe>';
}

}
?>

Online translations? What do you mean?

Are you just trying to get live streams?

Don’t use file_get_contents for making HTTP requests, it’s blocked on most hosts, you need to use cURL instead https://www.php.net/manual/en/function.curl-init.php

yes. i need to check every channel in array, and if its online - show it on site

Ok so you have a number of issues

  1. file_get_contents - you should be using curl
  2. Your URL construction is wrong
  3. You are requesting Helix, but using the Kraken Data pattern to parse the result

Finally, the streams API will let you look up 100 streams at once, and it’ll only return those that are live. You can take the response and compared that with your Names array if you want to show a offline message.

You can call:

$url = ‘https://api.twitch.tv/helix/streams?user_login=’ . implode(’&user_login=’, $names);

Then

$resullt = json_decode(theresponse);

foreach ($result->data as $stream) {
    echo '<iframe src="https://player.twitch.tv/?channel=' . strtolower($stream->user_name) . '" frameborder="0" allowfullscreen="true" scrolling="no" height="378" width="620"></iframe>';
}

You may need to be aware of this issue:

Which may catch you out on some streams, and you probably want to convert to user_id’s so you don’t have to update your names array if/when someone changes their Twitch username

Finally, finally, as per

You will need to update your code to use an oAuth token, which in this case will probably work best with an App Access Token (aka Server to Server)

so, i need something like this?

<?php
  $names[] = "xxxxxx";
$names[] = "xxxxxx";

$url = "https://api.twitch.tv/helix/streams?user_login=’ . implode(’&user_login=’, $names)";

foreach ($names as $channel) {
    $request_params = array(
        'client_id' => 'xxxxxxxxx'
    );
    $params = http_build_query($request_params);
    
    
    $result = json_decode(curl_init('https://api.twitch.tv/helix/streams/'. $channel . '/?'. $params));
    curl_setopt($result, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($result, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($result, CURLOPT_HEADER, false);
    $html = curl_exec($result);
    curl_close($result);
     

    $game_ID = $result -> stream -> id; 
    $stream_name = $result -> stream -> game;
    $stream_status = $result -> stream -> channel -> status; 
    $url_channel = $result -> stream -> channel -> url; 
    $img_preview = $result -> stream -> preview -> template; 

    foreach ($result->data as $stream) {
        echo '<iframe src="https://player.twitch.tv/?channel=' . strtolower($stream->user_name) . '" frameborder="0" allowfullscreen="true" scrolling="no" height="378" width="620"></iframe>';
    }


}


?>

You shouldn’t even use this in production code, it’s unsafe

Helix requires the clientID to be a header. And you didn’t declare an Auth token

No

No this is Kraken data formatting again

You also have no HTTP code checking or error checking

Something more like: (untested off the top of my head, doesn’t include how to fetch an oAuth token

<?php

    $names = [
        "xxxxxx",
        "xxxxxx"
    ];
    $status = [];
    foreach ($names as $name) {
        $status[$name] = false;
    }

    $url = "https://api.twitch.tv/helix/streams?user_login=’ . implode(’&user_login=’, $names)";

    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'Client-ID: ' . $client_id,
        'Authorisation: Bearer ' + token
    ));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $result = curl_exec($ch);
    $info = curl_getinfo($result);
    curl_close($ch);

    if ($info['http_code'] == 200) {
        $result = json_decode($result);
        if (json_last_error() == JSON_ERROR_NONE) {
            foreach ($result->data as $stream) {
                // do stuff with stream
                $name = strtolower($stream->user_name);
                $status[$name] = true;
            }
        } else {
            echo 'Failed to deocde JSON';
        }
    } else {
        echo 'Failed with ' . $info['http_code'];
    }

    foreach ($status as $name => $state) {
        if ($state) {
            echo '<iframe src="https://player.twitch.tv/?channel=' . $name) . '" frameborder="0" allowfullscreen="true" scrolling="no" height="378" width="620"></iframe>';
        } else {
            echo $name . ' not live';
        }
    }

i generated Oath token in this service https://twitchtokengenerator.com, cause this method from guide dont work for me:

GET https://id.twitch.tv/oauth2/authorize
    ?client_id=<your client ID>
    &redirect_uri=<your registered redirect URI>
    &response_type=code
    &scope=<space-separated list of scopes>

anyway this code don’t work… i think it’s some problem with checking the channel status. sorry for wasting your time

   <?php
    $names[] = "xxxxxx";
    $names[] = "xxxxxx";

    $status = [];
    foreach ($names as $name) {
        $status[$name] = false;
    }

    $url = "https://api.twitch.tv/helix/streams?user_login=’ . implode(’&user_login=’, $names)";
    
    $client_id = "xxxxxxxxx";
    $token = "xxxxxxxxx";

    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'Client-ID: ' . $client_id,
        'Authorisation: Bearer ' . $token
    ));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $result = curl_exec($ch);
    $info = curl_getinfo($result);
    curl_close($ch);

    if ($info['http_code'] == 200) {
        $result = json_decode($result);
        if (json_last_error() == JSON_ERROR_NONE) {
            foreach ($result->data as $stream) {
                // do stuff with stream
                $name = strtolower($stream->user_name);
                $status[$name] = true;
            }
        } else {
            echo 'Failed to decode JSON';
        }
    } else {
        echo 'Failed with ' . $info['http_code'];
    }

    foreach ($status as $name => $state) {
        if ($state) {
            echo '<iframe src="https://player.twitch.tv/?channel=' . $name . '" frameborder="0" allowfullscreen="true" scrolling="no" height="378" width="620"></iframe>';
        } else {
            echo $name . ' not live';
        }
    }
?>

now i getting this in browser:
Failed with xxxxxxxx not livexxxxxxxxx not live

you tried to generate a user token you need an App Access Token

Failed with xxxxxx isn’t valid, it should be a number.

You can update the code to spit out the body of the response if you want, and debug from there.

echo 'Failed with ’ . $info[‘http_code’];

becomes

echo 'Failed with ' . $info['http_code'] . ' - ' . $result . '<br />';

Should also debug out the URL to confirm it’s an expected URL.

is it possible to get it via browser just typing there this? and what scope do i need?

https://id.twitch.tv/oauth2/token
    ?client_id=<your client ID>
    &client_secret=<your client secret>
    &grant_type=client_credentials
    &scope=<space-separated list of scopes>

Server to server/app access tokens don’t/shouldn’t be generated via the browser, but server code

now i getting:

Failed with - Bad Request
xxxxxxxxxx not livexxxxxxxxx not live

Change

$url = “https://api.twitch.tv/helix/streams?user_login=’ . implode(’&user_login=’, $names)”;

to

$url = “https://api.twitch.tv/helix/streams?user_login=’ . implode(’&user_login=’, $names)”;
echo $url;

And confirm the URL you are trying to load?

this one
https://api.twitch.tv/helix/streams?user_login=’ . implode(’&user_login=’, Array)Failed with - Bad Request

Whats the compiled url you are calling? The one being passed to curl_init

you mean with real twitch name? i guess this is it:
https://api.twitch.tv/helix/streams?user_login=kektheking

Not sure why you are getting a bad request then.

And you have all this loop code to only look up one streamer?

no, there are two of them now, but there will be more later.

i just fixed the double quotes in the string, i guess this will be right
$url = "https://api.twitch.tv/helix/streams?user_login=" . implode('&user_login=', $names);

but now getting this error:
https://api.twitch.tv/helix/streams?user_login=crazyivan1&user_login=kekthekingFailed with - {"data":[],"pagination":{}}

Ok I tested the script.

You construct the URL badly, and I typoed the call to curl_getinfo.

it should be

$info = curl_getinfo($ch);

You put

$url = “https://api.twitch.tv/helix/streams?user_login=’ . implode(’&user_login=’, $names)”;

So the URL got screwed up isntead of being constructed correctly.

<?php
    $names[] = "xxxxxx";
    $names[] = "xxxxxx";

    $status = [];
    foreach ($names as $name) {
        $status[$name] = false;
    }

    $url = 'https://api.twitch.tv/helix/streams?user_login=' . implode('&user_login=', $names);

    $client_id = "xxxxxxxxx";
    $token = "xxxxxxxxx";

    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'Client-ID: ' . $client_id,
        'Authorisation: Bearer ' . $token
    ));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $result = curl_exec($ch);
    $info = curl_getinfo($ch);
    curl_close($ch);

    if ($info['http_code'] == 200) {
        $result = json_decode($result);
        if (json_last_error() == JSON_ERROR_NONE) {
            foreach ($result->data as $stream) {
                // do stuff with stream
                $name = strtolower($stream->user_name);
                $status[$name] = true;
            }
        } else {
            echo 'Failed to decode JSON';
        }
    } else {
        echo 'Failed with ' . $info['http_code'];
    }

    foreach ($status as $name => $state) {
        if ($state) {
            echo '<iframe src="https://player.twitch.tv/?channel=' . $name . '" frameborder="0" allowfullscreen="true" scrolling="no" height="378" width="620"></iframe>';
        } else {
            echo $name . ' not live';
        }
    }

man, you’re awesome. it’s working now, but i have mentioned some strange things. if stream is online, but there is a picture background, script thinks its offline, also if stream is video. i mean its was written before and now its gone online. is it normal? or it can be fixed somehow?

and about Oath token - i tried to get it on my hostiing using console with this, but dont get it anyway( and what is this “scope” atrribute and which one i need?

POST https://id.twitch.tv/oauth2/token
    ?client_id=<your client ID>
    &client_secret=<your client secret>
    &grant_type=client_credentials
    &scope=<space-separated list of scopes>