Check user if subscribed to my channel

Hello, I’m lost, I want to know when you enter my website if you are a subscriber, but I don’t know how to do it with this code:

<?php
	/**
	 * Class for handling all calls to the Twitch API
	 *
	 */
	class eciTwitchApi {
		/**
		 * @var api authorization domain
		 */
		const TWITTER_ID_DOMAIN = 'https://id.twitch.tv/';

		/**
		 * @var api endpoint calls domain
		 */
		const TWITTER_API_DOMAIN = 'https://api.twitch.tv/helix/';

		/**
		 * @var client id
		 */
		private $_clientId;

		/**
		 * @var client secret
		 */
		private $_clientSecret;

		/**
		 * @var access token
		 */
		private $_accessToken;

		/**
		 * @var refresh token
		 */
		private $_refreshToken;

		/**
		 * Constructor for this class
		 *
		 * @param string $clientId twitch client id
		 * @param string $clientSecret twitch client secret
		 * @param string $accessToken twitch access token
		 *
		 * @return void
		 */
		public function __construct( $clientId, $clientSecret, $accessToken = '' ) {
			// set client id
			$this->_clientId = $clientId;

			// set client secret
			$this->_clientSecret = $clientSecret;

			// set access token
			$this->_accessToken = $accessToken;
		}

		/**
		 * Get the login url
		 *
		 * @param array $redirectUri
		 *
		 * @return string
		 */
		public function getLoginUrl( $redirectUri ) {
			// request endpoint
			$endpoint = self::TWITTER_ID_DOMAIN . 'oauth2/authorize';

			// store state so we can check it once the user comes back to our redirect uri
			$_SESSION['twitch_state'] = md5( microtime() . mt_rand() );

			$params = array( // params for endpoint
				'client_id' => $this->_clientId,
				'redirect_uri' => $redirectUri,
				'response_type' => 'code',
				'scope' => 'user:read:email',
				'state' => $_SESSION['twitch_state']
			);

			// add params to endpoint and return the login url
			return $endpoint . '?' . http_build_query( $params );
		}

		/**
		 * Try and log a user in with Twitch
		 *
		 * @param string $code code from Twitch
		 * @param string $redirectUri redirect uri
		 *
		 * @return array
		 */
		public function tryAndLoginWithTwitch( $code, $redirectUri ) {
			// get access token
			$accessToken = $this->getTwitchAccessToken( $code, $redirectUri );

			// save status and message from access token call
			$status = $accessToken['status'];
			$message = $accessToken['message'];

			if ( 'ok' == $status ) { // we got an access token1
				// set access token and refresh token class vars 
				$this->_accessToken = $accessToken['api_data']['access_token'];
				$this->_refreshToken = $accessToken['api_data']['refresh_token'];

				// get user info
				$userInfo = $this->getUserInfo();

				// save status and message from get user info call
				$status = $userInfo['status'];
				$message = $userInfo['message'];
				
				if ( 'ok' == $userInfo['status'] && isset( $userInfo['api_data']['data'][0] ) ) { // we have user info!
					// log user in with info from get user info api call
					$this->_logUserInWithTwitch( $userInfo['api_data']['data'][0] );
				}
			}

			return array( // return status and message of login
				'status' => $status,
				'message' => $message
			);
		}

		/**
		 * Log a user in
		 *
		 * @param array $apiUserInfo user info from Twitch
		 *
		 * @return void
		 */
		private function _logUserInWithTwitch( $apiUserInfo ) {
			// save user info and tokens in the session
			$_SESSION['twitch_user_info'] = $apiUserInfo;
			$_SESSION['twitch_user_info']['access_token'] = $this->_accessToken;
			$_SESSION['twitch_user_info']['refresh_token'] = $this->_refreshToken;

			// boolean if user has signed up on our site before using social to login
			$_SESSION['eci_login_required_to_connect_twitch'] = false;
		
			// check for user with twitch id
			$userInfoWithId = getRowWithValue( 'users', 'twitch_user_id', $apiUserInfo['id'] );

			// check for user with email
			$userInfoWithEmail = getRowWithValue( 'users', 'email', $apiUserInfo['email'] );
		
			if ( $userInfoWithId || ( $userInfoWithEmail && !$userInfoWithEmail['password'] ) ) { // user was found by email/id log them in
				// get user id
				$userId = $userInfoWithId ? $userInfoWithId['id'] : $userInfoWithEmail['id'];

				// save twitch id and tokens to the user
				updateRow( 'users', 'twitch_user_id', $apiUserInfo['id'], $userId );
				updateRow( 'users', 'twitch_access_token', $this->_accessToken, $userId );
				updateRow( 'users', 'twitch_refresh_token', $this->_refreshToken, $userId );

				// get user info
				$userInfo = getRowWithValue( 'users', 'id', $userId );

				// update session so the user is logged in
				$_SESSION['is_logged_in'] = true;
				$_SESSION['user_info'] = $userInfo;
			} elseif ( $userInfoWithEmail && !$userInfoWithEmail['twitch_user_id'] ) { // user needs to enter their password to connect the account
				$_SESSION['eci_login_required_to_connect_twitch'] = true;
			} else { // user was not found in our database, sign them up and log them in
				$signupUserInfo = array( // data we need to insert the user in our database
					'email' => $apiUserInfo['email'], // email from Twitch response
					'first_name' => $apiUserInfo['display_name'], // using display_name as first name cause not first name in Twitch response
					'last_name' => '', // no last name in Twitch response
					'twitch_user_id' => $apiUserInfo['id'], // Twitch id from Twitch response
					'twitch_access_token' => $this->_accessToken, // access token from Twitch response
					'twitch_refresh_token' => $this->_refreshToken // refresh token from Twitch response
				);

				// sign user up
				$userId = signUserUp( $signupUserInfo );

				// get user info
				$userInfo = getRowWithValue( 'users', 'id', $userId );

				// update session so the user is logged in
				$_SESSION['is_logged_in'] = true;
				$_SESSION['user_info'] = $userInfo;
			}
		}

		/**
		 * Get a users info from Twitch
		 *
		 * @param void
		 *
		 * @return array
		 */
		public function getUserInfo() {
			// requet endpoint
			$endpoint = self::TWITTER_API_DOMAIN . 'users';

			$apiParams = array( // params for our api call
				'endpoint' => $endpoint,
				'type' => 'GET',
				'authorization' => $this->getAuthorizationHeaders(),
				'url_params' => array()
			);

			// make api call and return response
			return $this->makeApiCall( $apiParams );
		}

		/**
		 * Get authorization header for api call
		 *
		 * @param void
		 *
		 * @return array
		 */
		public function getAuthorizationHeaders() {
			return array( // this array will be used as the header for the api call
				'Client-ID: ' . $this->_clientId,
				'Authorization: Bearer ' . $this->_accessToken
			);
		}

		/**
		 * Get access token
		 *
		 * @param string $code code from Twitch
		 * @param string $redirectUri redirect uri
		 *
		 * @return array
		 */
		public function getTwitchAccessToken( $code, $redirectUri ) {
			// requet endpoint
			$endpoint = self::TWITTER_ID_DOMAIN . 'oauth2/token';

			$apiParams = array( // params for our api call
				'endpoint' => $endpoint,
				'type' => 'POST',
				'url_params' => array(
					'client_id' => $this->_clientId,
					'client_secret' => $this->_clientSecret,
					'code' => $code,
					'grant_type' => 'authorization_code',
					'redirect_uri' => $redirectUri
				)
			);

			// make api call and return response
			return $this->makeApiCall( $apiParams );
		}

		/**
		 * Make calls to the Twitch API
		 *
		 * @param array $params
		 *
		 * @return array
		 */
		public function makeApiCall( $params ) {
			$curlOptions = array( // curl options
				CURLOPT_URL => $params['endpoint'], // endpoint
				CURLOPT_CAINFO => PATH_TO_CERT, // ssl certificate
				CURLOPT_RETURNTRANSFER => TRUE, // return stuff!
				CURLOPT_SSL_VERIFYPEER => TRUE, // verify peer
				CURLOPT_SSL_VERIFYHOST => 2, // verify host
			);

			if ( isset( $params['authorization'] ) ) { // we need to pass along headers with the request
				$curlOptions[CURLOPT_HEADER] = TRUE;
				$curlOptions[CURLOPT_HTTPHEADER] = $params['authorization'];
			}

			if ( 'POST' == $params['type'] ) { // post request things
				$curlOptions[CURLOPT_POST] = TRUE;
                $curlOptions[CURLOPT_POSTFIELDS] = http_build_query( $params['url_params'] );
			} elseif ( 'GET' == $params['type'] ) { // get request things
				$curlOptions[CURLOPT_URL] .= '?' . http_build_query( $params['url_params'] );
			}

			// initialize curl
			$ch = curl_init();

			// set curl options
			curl_setopt_array( $ch, $curlOptions );

			// make call
			$apiResponse = curl_exec( $ch );

			if ( isset( $params['authorization'] ) ) { // we have headers to deal with
				// get size of header
				$headerSize = curl_getinfo( $ch, CURLINFO_HEADER_SIZE );

				// remove header from response so we are left with json body
				$apiResponseBody = substr( $apiResponse, $headerSize );

				// json decode response body
				$apiResponse = json_decode( $apiResponseBody, true );	
			} else { // no headers response is json string
				// json decode response body
				$apiResponse = json_decode( $apiResponse, true );
			}

			// close curl
			curl_close( $ch );

			return array(
				'status' => isset( $apiResponse['status'] ) ? 'fail' : 'ok', // if status then there was an error
				'message' => isset( $apiResponse['message'] ) ? $apiResponse['message'] : '', // if message return it
				'api_data' => $apiResponse, // api response data
				'endpoint' => $curlOptions[CURLOPT_URL], // endpoint hit
				'url_params' => $params['url_params'] // url params sent with the request
			);
		}
	}

Call to function:

if ( isset( $_GET[‘code’] ) && isset( $_GET[‘state’] ) && $_GET[‘state’] == $_SESSION[‘twitch_state’]
) {
$eciTwitchApi = new OAuthTwitch( TWITCH_CLIENT_ID, TWITCH_CLIENT_SECRET );
$twitchLogin = $eciTwitchApi->tryAndLoginWithTwitch( $_GET[‘code’], TWITCH_REDIRECT_URI );
}

$eciTwitchApi = new OAuthTwitch( TWITCH_CLIENT_ID, TWITCH_CLIENT_SECRET );
$twitchLoginUrl = $eciTwitchApi->getLoginUrl( TWITCH_REDIRECT_URI );

?>

Your code doesn’t seem to have any susbcriber chnecking logc.

The endpoint is documented here

Generally you would use a “two token” system, where you collect and store and use a broadcasters token to do the subscriber checks.

And use the users token just for login.

Then you only ask the broadcaster for permission to read the broadcasters subs

Alternatively you can use

Which would ask the user permission to read all the people that they sub to (which users generally will not prefer)

Then you would only juggle the one token.

The previous code, only registers the user and saves the token and the refresh of the token, I know it is a lot of annoyance to ask for an example, but everything I try gives me an error.
I would have to do something like this:

		public function getLoginUrl( $redirectUri ) {
		// request endpoint
		$endpoint = self::TWITTER_ID_DOMAIN . 'oauth2/authorize';

		// store state so we can check it once the user comes back to our redirect uri
		$_SESSION['twitch_state'] = md5( microtime() . mt_rand() );

		$params = array( // params for endpoint
			'client_id' => $this->_clientId,
			'redirect_uri' => $redirectUri,
			'response_type' => 'code',
			'scope' => '**channel:read:subscriptions**',
			'state' => $_SESSION['twitch_state']
		);

		// add params to endpoint and return the login url
		return $endpoint . '?' . http_build_query( $params );
	}

and here I should also put this I think:

	public function getUserInfo() {
		// requet endpoint
		$endpoint = self::TWITTER_API_DOMAIN . '**subscriptions**';

		$apiParams = array( // params for our api call
			'endpoint' => $endpoint,
			'type' => 'GET',
			'authorization' => $this->getAuthorizationHeaders(),
			'url_params' => array()
		);

		// make api call and return response
		return $this->makeApiCall( $apiParams );
	}

or do something like this with my code:

With this code:

if ($i[‘http_code’] == 200) {
$validation = json_decode($r);

    if (json_last_error() == JSON_ERROR_NONE) {
         // el token es bueno
         // vamos a obtener el usuario para el que es este token

        $ch = curl_init('https://api.twitch.tv/helix/subscriptions/events?broadcaster_id=507703972');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(
            'Client-ID: ' . CLIENT_ID,
            'Authorization: Bearer ' . $_SESSION['token']->access_token
        ));

        $r = curl_exec($ch);
        $i = curl_getinfo($ch);

        curl_close($ch);

It returns this to me, but does not put any subscribers:

Thats the events endpoint.

I’m assuming $_SESSION['token']->access_token is the token for ragnarok1978 and not the person logging in.

You should probably be using “Get Broadcaster Subscriptions” not “Get Broadcaster Subscription events”

And specify a user_id to do a one to one lookup.


        $ch = curl_init('https://api.twitch.tv/helix/subscriptions?broadcaster_id=507703972&user_id=' . $logged_in_user_id);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(
            'Client-ID: ' . CLIENT_ID,
            'Authorization: Bearer ' . $_SESSION['token']->access_token
        ));

event_data will be an object. so I guess your display function didn’t iterate the object in an object, hence it’s blank.

I get this error: An error occurred while searching for the user

Thats not a error I’m familiar with for that endpoint.

Whats the full URL you are calling?

https://api.twitch.tv/helix/subscriptions?broadcaster_id=507703972&user_id=’ . $logged_in_user_id

You did populate $logged_in_user_id with an the ID?

I’m doing something wrong:

$logged_in_user_id = ‘540802131’;
$ch = curl_init(‘https://api.twitch.tv/helix/subscriptions?broadcaster_id=507703972&user_id=’ . $logged_in_user_id);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Client-ID: ’ . CLIENT_ID,
'Authorization: Bearer ’ . $_SESSION[‘token’]->access_token
));

Your code looks correct.

OAuth redirect url, elsewhere

http://localhost/ragnarok1978/?error=redirect_mismatch&error_description=Parameter+redirect_uri+does+not+match+registered+URI&state=39NZnVIkGarpFA%3D%3D

That indicates the specified redirect_uri is not valid according to your dev console settings

now it works, for that user, but I have to do it one at a time, or you can verify all the users who sign up.
I get tier = 1000

Thats up to you depends where/how you want to do “is a sub” checks

Every time you register on my website, I want to know if you are a subscribed user or not, what should I use:
after=

Then you do the check as the user is logging in. But thats up to you depending on yoru architeture of your system/website

Or you have a database that stores that data and you check the DB instead.
The DB uses eventsub to stay up to date.
Then you don’t check at login from the API as you already have it in the DB

Gracia Barri, if I want everything to be stored in a database.