Pagination with Youtube API and integrations fields

Hello Kristian,

Here is a code that should work. I permit myself to remove the if else condition and use type=video in the url. Also, i m not using env var for the API key only for my tests. You can reput your env var (process.env.GOOGLE_API_KEY). For the pagination, we need to play with the nextPageToken yes.

const express = require('express');
const app = express();
const port = 3000;
const fetch = require('node-fetch');

const apiKey = 'YOUR_API_KEY';

const url = 'https://www.googleapis.com/youtube/v3/search?channelId=UCCNhmdvSnRNmuxTIYFybk5A&part=snippet,id&order=date&maxResults=50&type=video';

function getResult(token) {
    if (!token) {
        return fetch(`${url}&key=${apiKey}`).then(response => response.json());
    } else {
        return fetch(`${url}&key=${apiKey}&pageToken=${token}`)
            .then(response => response.json());
    }
}

app.get('/videos', async (req, res) => {
    let formattedData = {};
    let formattedResults = [];
    let json = undefined;
    const page = req.query.page;


    if (page && page > 0) {
        let token = undefined;
        for (let i = 0; i < page; i++) {
            json = await getResult(token)
                .then(json => {
                    token = json.nextPageToken;
                    return json;
                })
        }
    } else {
        json = await getResult()
    }


    json.items.forEach(item => {
        let date = item.snippet.publishedAt;
        let TS = new Date(date).getTime();
        let TSFLOAT = parseInt(TS);
        let id = item.id.videoId;

        formattedResults.push({
            'id': id,
            'title': item.snippet.title,
            'description': item.snippet.description,
            'image_url': item.snippet.thumbnails.default.url,
            'last_update': TSFLOAT,
            'blob': {
                'id': id,
                'thumb': item.snippet.thumbnails
            }
        });
    });


    formattedData = {
        "results_size": 150,
        "results": formattedResults
    };
    res.json(formattedData);
});

app.listen(port, () => console.log(`Example app listening at http://localhost:${port}`));

The only issue with that solution is the fact that you need to fetch the first x - 1 page to get the x page. A better solution would be to store all data somewhere in your system as a cache (with expiration after like 30 minutes or 1 hour). And then return only the cached result. But that’s an other subject. For small YouTube channel it’s ok to fetch few times to get the data that you want.

Also, don’t hardcode results_size in the response. I would use pageInfo.totalResults from the YouTube API response to populate this field.

Thank you,
Raphaël