Keep having 401 error code when trying to reach channel point redemption

Hello !

I’m working for a Twitch streamer and im trying to get back user informations about channel point redemptions.
I have a script that get a token from oAuth with the client ID that he created in his own account and then I try to reach informations about the redemption API but I keep having 401 unauthorized -> incorrect user authorization

Here’s my code

const TWITCH_OAUTH_URL = "https://id.twitch.tv/oauth2/authorize";
const CLIENT_ID = "...";  
const REDIRECT_URI = "https://voltext.github.io/";
const RESPONSE_TYPE = "token";
const SCOPES = [
    "user:read:email",
    "channel:read:redemptions",
].join(" ");

function encodeQueryString(params) {
    let items = []
    for (let key in params) {
        let value = encodeURIComponent(params[key]);
        items.push(`${key}=${value}`);
    }
    return items.join("&");
}

function getUrlQueryStringParams() {
    const items = location.hash.slice(1).split("&");
    const params = {};

    for (let i in items) {
        let key = decodeURIComponent(items[i].split("=")[0]);
        let value = encodeURIComponent(items[i].split("=")[1]);
        params[key] = value;
    }

    return params;
}

function makeGetJsonRequest(url, params=null, headers=null) {
    if (params) {
        url = `${url}?${encodeQueryString(params)}`;
    }

    return new Promise((resolve, reject) => {
        var xhr = new XMLHttpRequest();

        xhr.onreadystatechange = function() {
            if (xhr.readyState === 4 && xhr.status === 200) {
                try {
                    const responseJson = JSON.parse(xhr.responseText);
                    resolve(responseJson);
                } catch (error) {
                    reject(error);
                }
            }
        };

        xhr.onerror = reject;

        xhr.open("GET", url, true);

        if (headers) {
            for (let header in headers) {
                xhr.setRequestHeader(header, headers[header]);
            }
        }

        xhr.send()
    });
}

function twitchAuthentification() {
    const params = {
        client_id: CLIENT_ID,
        redirect_uri: REDIRECT_URI,
        response_type: RESPONSE_TYPE,
        scope: SCOPES,
    };
    location.href = `${TWITCH_OAUTH_URL}?${encodeQueryString(params)}`;
}

function twitchIsAuthenticated() {
    const params = getUrlQueryStringParams();
    if (params.access_token !== undefined) return true;
    return false;
}


function main() {
    if (!twitchIsAuthenticated()) {
        twitchAuthentification();
    }
    console.log("Connecté");
    const params = getUrlQueryStringParams();

    makeGetJsonRequest("https://api.twitch.tv/helix/channel_points/custom_rewards", {
            "broadcaster_id": STREAMER_ID,
        }, {
            "client-id": CLIENT_ID,
            "Authorization": `Bearer ${params.access_token}`,
        })
        .then(result => console.log(result))
        .catch(error => console.error(error));
}

window.onload = main;

It seems that im doing something wrong but I did not understand what.
Thank you for your time and your help.
Sincerelly

Little information about this subject. When I put my own Client-Id, this script works correctly and I get back my own channel point redemption. But actually I want to get back his channel point redemption and not mine

The owner of the ClientID is irrelevant.

It’s all about whom authenticates/grant access to the clientID

The user you want to read, STREAMER_ID needs to authenticate.

Here you are using implicit auth which means that when you send this page to someone else, they login and only have access to their own rewards/redemptions on their channel as you are only operating as that user.

You cannot read USERB redemptions when you are logged in as USERA in your code.

So here, you are potentially running the wrong authentication type, since there is no way to store the token somewhere else for your usage.

Normally you would create a portal, that uses your ClientID, that uses regular oAuth, to get permission/a token from STREAMER_ID store that token on your server.

Then when your script that needs to do things with redemptions would load and use that token (refresh if needed)

Thank you for your fast answer.

Yeah, I just read the documentation more slowly and yeah it seems that I do not use the correct auth auth. I use the response_type token when I think I’ve to use the response_type = code and then build around.
Im not really aware of the Twitch API working but I think I’ll learn with time.

Just to be sure I understand your message.
If I use my own Client-ID from my app that has no importance if I do not use the streamer one ?
Can you please give me more information about the working system api to know what am I doing wrong. That’s a bit blur in my mind not gonna lie.

It’s “industry standard oAuth”, so a lot of services use this authetication mechanism for third party access to data, Twitch, YouTube/Google, Twitter, Discord to name a few. It’s all oAuth to get access

it can be done with type=token, but then you need to capture and store the token. Then after then token expires the streamer will need to reauthenticate and provide a new token

With type=code you exchange the code for an access_token and refresh_token then you can use the refresh_token when the access_token expires.

The ClientID creates a “name” for your script so the streamer can see and disconnect it/know what they are linked it/granted permissions to on Twitch

The owner of the clientID is irrelevant.

The ClientID + a constructure oAuth link, will create a link between the authenticating user, the scopes and the clientID to generate an access_token aka password to access the authentication users account and read/write data about the account, if relevant scopes granted.

So if I want to read channel points for lirik, I would ask lirik to go to my website and click the link, grant access and store the returned token.

If I want to read channel points for ninja, I would ask ninja to go to my website and click the link, grant access and store the returned token.

If I want to read channel points for cohhcarnage, I would ask cohhcarnage to go to my website and click the link, grant access and store the returned token.

In all three examples it’s all the same ClientID, mine.

A ClientID doesn’t give you immediate access to the Streamers account. There is no connection between a ClientID and a Twitch User.

A clientID only “exists” on dev.twitch.tv it doesn’t link to anything on twitch.tv until you do an oAuth loop and a user creates an access link betwen their account and the clientID.

Any clientID can obtain scoped permissions to a Twitch User Account.

That cannot be more clear than that. Thank you so much
Have a great day

Thiere is also this

For further reading on oAuth

1 Like

I will definitely read that.
Thank you so much man.

1 Like

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