Unable to get app access token

Hey all,

I am building a website where I will need access to finding specific games and streamers a user searches for. In order for me to search for games and streamers, I need to use OAuth Authentication.

It seems to me that I need to use the OAuth client credentials flow.

I have followed the example and am trying to do the API call in Node.js using Express, but I am getting an error called Unexpected token p in JSON at position 4. It seems to be some sort of FetchError but I can not find the solution everywhere. I will link my code below and would appreciate any help I can get! I am ommiting my client_id and client_secret from the code for obvious reasons.

router.post('/', async (req, res) => {
    console.log('name route it')
    try {
        const tokenCall = await fetch('https://id.twitch.tv/oauth2/token?client_id=<id>&client_secret=<secret>&grant_type=client_credentials', {
        })
        const token = await tokenCall.json()
        console.log(token, '<- token in Twitch call')
    } catch (err) {
        console.log(err, '<- err in token call')
    }
})

Thank you!

Check the contents of tokenCall (before trying to JSON parse) to check it’s what you expect it should be. Before trying to json parse it

Luckily I tried that before but really don’t get much info from the response. It does show the status as 404 though, but it isn’t hitting the catch error so I am not quite sure what this means.

Response {
  size: 0,
  timeout: 0,
  [Symbol(Body internals)]: {
    body: PassThrough {
      _readableState: [ReadableState],
      readable: true,
      _events: [Object: null prototype],
      _eventsCount: 2,
      _maxListeners: undefined,
      _writableState: [WritableState],
      writable: false,
      allowHalfOpen: true,
      _transformState: [Object],
      [Symbol(kCapture)]: false
    },
    disturbed: false,
    error: null
  },
  [Symbol(Response internals)]: {
    url: 'https://id.twitch.tv/oauth2/token?client_id=<id>&client_secret=<secret>&grant_type=client_credentials',
    status: 404,
    statusText: 'Not Found',
    headers: Headers { [Symbol(map)]: [Object: null prototype] },
    counter: 0
  }
} <- token in Twitch call

Your fetch request made a HTTP Get request instead of a HTTP Post request

Try

const tokenCall = await fetch('https://id.twitch.tv/oauth2/token?client_id=<id>&client_secret=<secret>&grant_type=client_credentials', { method: 'post' 
    })

It worked! OMG thank you! I am wondering why I had to do that. I was sending a POST request from Postman and I had it labeled as router.post in the back end as well so I am wondering why Twitch needed this extra step.

So what is the best approach for using the token? This is the first time I have ever had to do this with an API.

Is it bad to get a token on every API request when I need to access data such as games, channels, etc. from Twitch?

yes

A token is valid for 60 days (check the expires time (in seconds) returned in the JSON blob

You should obtain, store and reuse a token until it is close to expiration

Thanks for the info! Going to have to learn how to do that, so good to know!