遵循YouTube Data API Node.js快速入门教程遇构造函数错误求助
I’ve run into this exact issue before—this happens because the official quickstart tutorial uses code written for old versions of google-auth-library (v0.x), but npm now installs the latest v2+ version by default, which has a completely different API structure. Let’s break down why your two attempts didn’t work, then fix it properly.
Why Your Previous Fixes Failed
Downgrading to
google-auth-library@0.12.0:
You only downgraded the auth library, but didn’t match it with a compatible version ofgoogleapis. Newergoogleapisversions expect different parameter formatting, which caused theRequired parameter: parterror (even though your code includes thepartparameter—version mismatch broke the API call).Using
const { GoogleAuth } = require('google-auth-library');:
The newer library doesn’t exposeOAuth2as a property of aGoogleAuthinstance. Instead, you need to importOAuth2Clientdirectly, which is why you got theTypeError: auth.OAuth2 is not a constructorerror.
Solution 1: Use the Latest Libraries (Recommended)
This is the best approach since old library versions have security vulnerabilities. Here’s how to update your code:
Step 1: Install Latest Dependencies
npm install googleapis google-auth-library --save
Step 2: Update Your Code
Replace the relevant parts of your code with these changes:
- Replace the old auth library import with the new
OAuth2Clientimport - Rewrite the
authorizefunction to use the new client directly
Here’s the full updated code:
var fs = require('fs'); var readline = require('readline'); var google = require('googleapis'); // Updated import for the latest auth library const { OAuth2Client } = require('google-auth-library'); // If modifying these scopes, delete your previously saved credentials // at ~/.credentials/youtube-nodejs-quickstart.json var SCOPES = ['https://www.googleapis.com/auth/youtube.readonly']; var TOKEN_DIR = (process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE) + '/.credentials/'; var TOKEN_PATH = TOKEN_DIR + 'youtube-nodejs-quickstart.json'; // Load client secrets from a local file. fs.readFile('client_secret.json', function processClientSecrets(err, content) { if (err) { console.log('Error loading client secret file: ' + err); return; } // Authorize a client with the loaded credentials, then call the YouTube API. authorize(JSON.parse(content), getChannel); }); /** * Create an OAuth2 client with the given credentials, and then execute the * given callback function. * * @param {Object} credentials The authorization client credentials. * @param {function} callback The callback to call with the authorized client. */ function authorize(credentials, callback) { var clientSecret = credentials.installed.client_secret; var clientId = credentials.installed.client_id; var redirectUrl = credentials.installed.redirect_uris[0]; // Use OAuth2Client directly instead of googleAuth constructor var oauth2Client = new OAuth2Client(clientId, clientSecret, redirectUrl); // Check if we have previously stored a token. fs.readFile(TOKEN_PATH, function (err, token) { if (err) { getNewToken(oauth2Client, callback); } else { oauth2Client.credentials = JSON.parse(token); callback(oauth2Client); } }); } /** * Get and store new token after prompting for user authorization, and then * execute the given callback with the authorized OAuth2 client. * * @param {google.auth.OAuth2} oauth2Client The OAuth2 client to get token for. * @param {getEventsCallback} callback The callback to call with the authorized * client. */ function getNewToken(oauth2Client, callback) { var authUrl = oauth2Client.generateAuthUrl({ access_type: 'offline', scope: SCOPES }); console.log('Authorize this app by visiting this url: ', authUrl); var rl = readline.createInterface({ input: process.stdin, output: process.stdout }); rl.question('Enter the code from that page here: ', function (code) { rl.close(); oauth2Client.getToken(code, function (err, token) { if (err) { console.log('Error while trying to retrieve access token', err); return; } oauth2Client.credentials = token; storeToken(token); callback(oauth2Client); }); }); } /** * Store token to disk be used in later program executions. * * @param {Object} token The token to store to disk. */ function storeToken(token) { try { fs.mkdirSync(TOKEN_DIR); } catch (err) { if (err.code != 'EEXIST') { throw err; } } fs.writeFile(TOKEN_PATH, JSON.stringify(token)); console.log('Token stored to ' + TOKEN_PATH); } /** * Lists the names and IDs of up to 10 files. * * @param {google.auth.OAuth2} auth An authorized OAuth2 client. */ function getChannel(auth) { var service = google.youtube('v3'); service.channels.list({ auth: auth, part: 'snippet,contentDetails,statistics', forUsername: 'GoogleDevelopers' }, function (err, response) { if (err) { console.log('The API returned an error: ' + err); return; } var channels = response.items; if (channels.length == 0) { console.log('No channel found.'); } else { console.log('This channel\'s ID is %s. Its title is \'%s\', and ' + 'it has %s views.', channels[0].id, channels[0].snippet.title, channels[0].statistics.viewCount); } }); }
Solution 2: Use Compatible Old Versions (If You Want to Keep the Original Code)
If you prefer to use the exact code from the tutorial, you need to install versions of googleapis and google-auth-library that work together:
npm uninstall googleapis google-auth-library --save npm install googleapis@27 google-auth-library@0.12.0 --save
This will match the versions the tutorial was written for, and your original code will run without errors (no need to modify any code).
内容的提问来源于stack exchange,提问作者Gilad

