Generating a new authentication code programmatically

Hello, there

I’m writng a small Python script that is supposed to retrieve the total number of subscribers of my own Twitch channel in order to update a page on my static page generated website. I have no need for immediate update of the page, so I have chosen to use the /helix/subscriptions API instead of the webhooks to obtain the number of subscribers.
This script would be executed in a Cron task once a day.

After reading the forums, I have discovered that I must use the Authorization code flow in order to be authorized getting this information from my own account (which makes sense). My problem is that the code I receive after completing the https://id.twitch.tv/oauth2/authorize seems to return a code I can use only once to authenticate, making my script requiring me to always re-authenticate manually to get the new code.

This is what my script looks currently like:

req = requests.post("https://id.twitch.tv/oauth2/token?client_id=%s&client_secret=%s&code=%s&grant_type=authorization_code&scope=channel:read:subscriptions&redirect_uri=http://localhost" % (CLIENT_ID, CLIENT_SECRET, CHANNEL_CODE))
print(req.json())
req.raise_for_status()
token = req.json()['access_token']

req = requests.get(
    'https://api.twitch.tv/helix/search/channels?query=%s' % TWITCH_CHANNEL,
    headers={'client-id': CLIENT_ID, 'Authorization': 'Bearer %s' % token}
)
req.raise_for_status()
channel_id = req.json()['data'][0]['id']

req = requests.get(
    'https://api.twitch.tv/helix/subscriptions?broadcaster_id=%s' % channel_id,
    headers={'client-id': CLIENT_ID, 'Authorization': 'Bearer %s' % token}
)
req.raise_for_status()
total_subs = req.json()['total']

print(total_subs)

If I visit the https://id.twitch.tv/oauth2/authorize?... URL and then copy the code I get back in the URL in my script, then the script works and I correctly get the number of subscribers.
But if I run the script a second time immediately, the first request fails with the following error:

{'status': 400, 'message': 'Invalid authorization code'}

And then I need to visit again the https://id.twitch.tv/oauth2/authorize?... URL to get a new code.

Given the application is correctly authorized with the good scopes on my account, is there any way to get the new code without having to visit the https://id.twitch.tv/oauth2/authorize?..., so I can consume the API with the authorizations of my account?

Thanks

When you use this code, the API returns an access token and a refresh token.

When the access token expires, use the refresh token to get a new access token.

TLDR: you are storing and attempting to use the wrong thing to get a new access token.

Oh, I see!
Is there a way to do it in a stateless way (i.e. without having to store anything), or is this the only way to get authenticated correctly?

If you don’t store the token, how do you reuse the token.

If you don’t store the refresh token how do you use that token to get a new access token.

As a minimum the refresh token must be stored.

There is no way to get the initial access token/refresh token in a headless way since a user token requires the browser to run the oAuth flow.

So if you want no state and you want to read private data on a users account.
You can’t do that. Something has to be stored after it is generated from a user manual interaction step.

If you only intend to read public data you can use a client credentials token instead Getting OAuth Access Tokens | Twitch Developers

But if you need to do actions on a user account then you need state

OK, thanks for your very quick reply :slight_smile:

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