Right Token flow for Getting Subscriber Points (PHP)

I think I’m either using the wrong authentication flow to get the information I want, or I’m looking in the wrong part of the API for what I want.

I’m using the OAuth Client Credentials flow:
Give: ID, Secret, Grant (client_credentials), scope (channel:read:subscriptions)
Get: Bearer Access Token

With that I make API calls to turn my username into a user ID and can get my follow count, but trying to get my subscriber point count returns an array with Error / 401 / “Missing scope: channel:read:subscriptions or channel_subscriptions”

I found this thread: Response not contains refresh token

which suggests I’m doing this the wrong way round if I need to select a scope. The flow for specifying a scope would be OAuth Client Credentials Flow. The flow there sounds like I’d ask the user to click on a link, the ‘accept,’ get bounced to another screen for a key, then the key returns to an app and…I’m just running one page of code that I hope to refresh in the background in OBS to keep the follow and sub point count updated in a text file, there’s no app or anything around it.

What should I be looking into next? Here’s the code so far:

<?php


function get_your_token_curl($url) {
	

	$ch = curl_init();	

	curl_setopt($ch, CURLOPT_URL,$url);
	curl_setopt($ch, CURLOPT_POST, 1);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	curl_setopt($ch, CURLOPT_POSTFIELDS, array (
				"client_id" => CLIENT_ID,
				"client_secret" => CLIENT_SECRET,
				"grant_type" => "client_credentials",
				"scope" => "channel:read:subscriptions" 
				
				) //close array
				);
	
	$data = curl_exec($ch);
	curl_close($ch);
	return $data;
	
}

function file_get_contents_curl($url) {
	$ch = curl_init();
	
	
	curl_setopt($ch, CURLOPT_AUTOREFERER, TRUE);
	curl_setopt($ch, CURLOPT_HTTPHEADER, array (
	
		"Client-ID: " . CLIENT_ID,
		"Authorization: Bearer " . ACCESS_TOKEN
		
	
	) //close array
	);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	curl_setopt($ch, CURLOPT_URL, $url);
	curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);     
	
	$data = curl_exec($ch);
	curl_close($ch);
	
	
	return $data;
	
}



define("CLIENT_ID", "<client ID from developer dashboard>");
define("CLIENT_SECRET", "<client secret form developer dashboard>");

//get App Access token
$url = "https://id.twitch.tv/oauth2/token";
$json_array = json_decode(get_your_token_curl($url), true);
define("ACCESS_TOKEN", $json_array['access_token']);


//get userID
$username = $_GET["username"];
$url = "https://api.twitch.tv/helix/users?login=" . $username;
$json_array = json_decode(file_get_contents_curl($url), true);
$userID = $json_array['data'][0]['id'];


//get Followers
$url = "https://api.twitch.tv/helix/users/follows?to_id=" . $userID;
$json_array = json_decode(file_get_contents_curl($url), true);


$followers = $json_array['total'];

//get Sub Points
$url = "https://api.twitch.tv/helix/subscriptions?broadcaster_id=" . $userID;
$json_array = json_decode(file_get_contents_curl($url), true);
print_r($json_array);
echo $json_array['points'];

?>

This is the wrong kind of token.

You need a User Access Token.

Client Credentials doesn’t represent the user.

You have the right scope but the wrong token type.

This is correct.

You need a “webpage” to get a token.
Then when you have that token you can feed it to an app that does stuff as needed. And refresh the token as needed using the refresh token.

If you need to do anything that involves protected user data, such as sub points, then you need a user token and NOT a client_credentials token.

client_credentials only works for public data (some exceptions)

The alternative is to use implict auth, but then the token will die after 60 days and you need to manually feed it a new token.

Generally for “browser source” type things, the browser source connects to an extenral service, and that serice handles the data handleing and token schnanigans

I ended up going the implicit auth route, and now I have access to the stats I wanted! I am doing it in a bit hamfisted way – my redirect URI is just a landing page so I can grab the bearer token right from the address bar, and I manually feed it into my PHP code.

I do have a website set up with SSL, but I wouldn’t know where to start securely storing tokens and the like on the webserver. Is it a big issue if I’m just running my API lookups off of XAMPP from localhost?