Last active
July 11, 2023 20:30
-
-
Save pascaljp/aad217db25fddd09e9c63407b87b5ea3 to your computer and use it in GitHub Desktop.
Youtube Data APIを用い、アカウント名'GoogleDevelopers'の最新の動画の最新のコメントを取ってくるサンプルプログラム
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Reference: https://developers.google.com/youtube/v3/quickstart/nodejs?hl=ja | |
// This program loads client secrets from a local file (~/.credentials/youtube-nodejs-quickstart.json). | |
// To set up the client secret, | |
// 1. visit https://console.cloud.google.com/. | |
// 2. Enable YouTube API. | |
// 3. Create an OAuth 2.0 client ID for a "Desktop Application". | |
// 4. Download the client secret file as a JSON file. | |
const fs = require('fs'); | |
const readline = require('readline'); | |
const {google} = require('googleapis'); | |
const OAuth2 = google.auth.OAuth2; | |
// If modifying these scopes, delete your previously saved credentials | |
// at ~/.credentials/youtube-nodejs-quickstart.json | |
const SCOPES = [ | |
'https://www.googleapis.com/auth/youtube.readonly', | |
'https://www.googleapis.com/auth/youtube.force-ssl' | |
]; | |
const TOKEN_DIR = (process.env.HOME || process.env.HOMEPATH || | |
process.env.USERPROFILE) + '/.credentials/'; | |
const TOKEN_PATH = TOKEN_DIR + 'youtube-nodejs-quickstart.json'; | |
// Just an example! | |
const YOUTUBE_ACCOUNT_NAME = 'GoogleDevelopers'; | |
async function main() { | |
try { | |
const content = fs.readFileSync('client_secret.json'); | |
// Authorize a client with the loaded credentials, then call the YouTube API. | |
const token = await authorize(JSON.parse(content)); | |
const channelId = await getChannelId(token); | |
const videos = await getMovies(token, channelId); | |
if (videos.length == 0) { | |
console.log('No movie found'); | |
process.exit(0); | |
} | |
const videoId = videos[0].id.videoId; | |
console.log('The movie id is %s', videoId); | |
const comments = await getComments(token, videoId); | |
console.log('Comments:'); | |
console.log(comments.map(comment => comment.snippet.topLevelComment)); | |
} catch (err) { | |
console.log('Error loading client secret file: ' + err); | |
} | |
} | |
main(); | |
/** | |
* 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: any) { | |
return new Promise(async (resolve, reject) => { | |
const clientSecret = credentials.installed.client_secret; | |
const clientId = credentials.installed.client_id; | |
const redirectUrl = credentials.installed.redirect_uris[0]; | |
const oauth2Client = new OAuth2(clientId, clientSecret, redirectUrl); | |
// Check if we have previously stored a token. | |
try { | |
const token = fs.readFileSync(TOKEN_PATH); | |
oauth2Client.credentials = JSON.parse(token); | |
resolve(oauth2Client); | |
} catch { | |
resolve(await getNewToken(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. | |
*/ | |
async function getNewToken(oauth2Client: typeof OAuth2) { | |
return new Promise((resolve, reject) => { | |
const authUrl = oauth2Client.generateAuthUrl({ | |
access_type: 'offline', | |
scope: SCOPES | |
}); | |
console.log('Authorize this app by visiting this url: ', authUrl); | |
const rl = readline.createInterface({ | |
input: process.stdin, | |
output: process.stdout | |
}); | |
rl.question('Enter the code from that page here: ', (code: string) => { | |
rl.close(); | |
oauth2Client.getToken(code, function(err: any, token: string) { | |
if (err) { | |
console.log('Error while trying to retrieve access token', err); | |
return; | |
} | |
oauth2Client.credentials = token; | |
storeToken(token); | |
resolve(oauth2Client); | |
}); | |
}); | |
}); | |
} | |
/** | |
* Store token to disk be used in later program executions. | |
* | |
* @param {Object} token The token to store to disk. | |
*/ | |
function storeToken(token: string) { | |
try { | |
fs.mkdirSync(TOKEN_DIR); | |
} catch (err: any) { | |
if (err.code != 'EEXIST') { | |
throw err; | |
} | |
} | |
fs.writeFile(TOKEN_PATH, JSON.stringify(token), (err: any) => { | |
if (err) throw err; | |
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. | |
*/ | |
async function getChannelId(auth: typeof OAuth2): Promise<string> { | |
const service = google.youtube('v3'); | |
try { | |
// https://developers.google.com/youtube/v3/docs/channels/list?hl=ja | |
const response = await service.channels.list({ | |
auth: auth, | |
part: 'snippet,contentDetails,statistics', | |
forUsername: YOUTUBE_ACCOUNT_NAME | |
}); | |
const channels = response.data.items; | |
if (channels.length == 0) { | |
console.log('No channel found.'); | |
process.exit(0); | |
} | |
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); | |
return channels[0].id; | |
} catch (err: any) { | |
console.log('The API returned an error: ' + err); | |
process.exit(1); | |
} | |
} | |
async function getMovies(auth: typeof OAuth2, channelId: string): Promise<any[]> { | |
const service = google.youtube('v3'); | |
try { | |
// https://developers.google.com/youtube/v3/docs/search/list?hl=ja | |
const response = await service.search.list({ | |
auth: auth, | |
part: 'snippet', | |
channelId: channelId, | |
maxResults: 1, | |
order: 'date', | |
}); | |
const movies = response.data.items; | |
return movies; | |
} catch (err: any) { | |
console.log('The API returned an error: ' + err); | |
process.exit(1); | |
} | |
} | |
async function getComments(auth: typeof OAuth2, videoId: string): Promise<any[]> { | |
const service = google.youtube('v3'); | |
try { | |
// https://developers.google.com/youtube/v3/docs/commentThreads/list?hl=ja | |
const response = await service.commentThreads.list({ | |
auth: auth, | |
part: 'id,replies,snippet', | |
videoId: videoId, | |
order: 'time', | |
textFormat: 'plainText', | |
}); | |
const comments = response.data.items; | |
return comments; | |
} catch (err: any) { | |
console.log('The API returned an error: ' + err); | |
process.exit(1); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment