Benjamin-Loison / YouTube-operational-API

YouTube operational API works when YouTube Data API v3 fails.
401 stars 52 forks source link

Invalid `nextPageToken` for `popular` `part` in `channels` endpoint #236

Open krasnoludkolo opened 9 months ago

krasnoludkolo commented 9 months ago

Related to #235

I want to collect all videos from channel which is automatically created by YouTube. I'm using new popular part added to channels endpoint.

I'm making request

/channels?part=popular&id=UC9r_nQL7uZ3eXQRFwzX7xZQ

In response I got

items[0].nextPageToken

which I'm using for next request:

/channels?part=popular&id=UC9r_nQL7uZ3eXQRFwzX7xZQ&pageToken=4qmFsgLuAhIYVUM5cl9uUUw3dVozZVhRUkZ3elg3eFpRGqgCRWdBWUF5QUFNQUU0QWVvRHl3RkhjRlZDVjI5WlFrTnZUVUpEYVhRMVpFWTVkMWxYWkd4WU0wNTFXVmhDZW1GSE9UQllNazUyWW01U2JHSnVVbVprYlZaNVpFZHNhbGxYZUhwWU0wcHNXakpzZG1KdFJuTkZhRGx5VGpCV2NsUjZiRXRoVjBrMVl6Rk9NMU13VGpaUlZ6RkVWVWhPZVZreFVteFJNMmQwVFcxb2JrZHFUVUZCUjFaMVFVRkdWbFYzUVVKV1ZrMUJRVkZDVmxGNmJIbFlNalZTVkVSa01WZHFUbXhYUmtaVFVtNWtObGRFWkRSWGJFVkJRVkZGUWtGQlFVSkJRVUZDUVZGRWVUSnlUM0ZEWjFwQlFrVm5UVlZCZHclM0QlM0SaAiZicm93c2UtZmVlZFVDOXJfblFMN3VaM2VYUVJGd3pYN3haUTgwOA%253D%253D%2CCgtjTVh2QVJidTBrVSjRirOuBjIKCgJVUxIEGgAgNA%253D%253D

in response I got

{'code': 400, 'message': 'Invalid pageToken'}
Benjamin-Loison commented 9 months ago

It seems to be an encoding issue, as discussed on Discord. It was proposed to use urldecode at https://github.com/Benjamin-Loison/YouTube-operational-API/blob/a1a9a7c3ea738153fc2400ec40ed4a742ef90885/channels.php#L76 but I would prefer a solution at the response sent level than at the parameters receiving level, because it would possibly simplify the response sent and hence correct the parameters received.

While we do not know the standards having a solution working for these 3 cases (while it currently works for the first 2) seems to be appropriate:

Note that this issue may be encountered for all paginations of this API and possibly other parameters, hence being quite sure of what we are doing seems necessary.

https://www.php.net/manual/en/function.urldecode.php

Seems related to #114.

Own testing script:

import requests

channelId = 'UC9r_nQL7uZ3eXQRFwzX7xZQ'

baseUrl = f'http://localhost/YouTube-operational-API/channels' # ?part=popular&id={channelId}

nextPageToken = ''
while True:
    params = {
        'part': 'popular',
        'id': channelId,
    }
    if nextPageToken:
        params['pageToken'] = nextPageToken
    url = baseUrl
    #url = baseUrl + (f'&pageToken={nextPageToken}' if nextPageToken else '')
    #params = None
    response = requests.get(url, params = params).json()
    item = response['items'][0]
    for video in item['popular']:
        print(video['title'])
    nextPageToken = item.get('nextPageToken')
    if not nextPageToken:
        break

As we made some progress thanks to today investigation, that I am not very keen with what should be done and that I am a bit in a hurry, I postpone properly solving this issue.

Benjamin-Loison commented 9 months ago

https://www.php.net/manual/en/json.constants.php https://www.php.net/manual/en/function.json-encode.php