node.js - YouTube Data v3 API - 如何从频道请求所有视频?
问题描述
我正在编写一个 Node.js 脚本,它将在 Lambda 中运行,以通过 YouTube Data v3 API 定期为我的组织的一个频道请求每个视频(公共、未列出或私有)的列表。为了做到这一点,似乎有两个步骤:
- 执行频道/列表调用https://developers.google.com/youtube/v3/docs/channels/list以获取“上传”播放列表。
const channelResult = await google.youtube('v3').channels.list({
auth: youtubeApiKey,
part: ['snippet', 'contentDetails'],
id: ["my_channel_id"]
});
- 执行 playlistItems/list https://developers.google.com/youtube/v3/docs/playlistItems/list以查看所有视频。
const videosResult = await google.youtube('v3').playlistItems.list({
auth: youtubeApiKey,
part: ['snippet', 'status'],
playlistId: "my_uploads_playlsit_id"
});
这只会作为运行云的脚本执行;没有用户界面或浏览器组件。当我将那里的唯一视频设置为公开时,这一切似乎都在我的测试频道中起作用。但是,如果我将其设置为私有,我会得到:
The playlist identified with the request's <code>playlistId</code> parameter cannot be found.
我必须做什么才能访问我频道的上传播放列表并显示私人视频?谢谢!
解决方案
在原始问题评论中@stvar 的帮助下,我能够做到这一点。流程是这样的:
- 通过启用 API 和服务从 Google Developers Console 启用 YouTube 数据 API v3。
- 在 YouTube Data API v3 的“凭据”窗格下创建一个新的 OAuth 客户端 ID,然后选择桌面应用程序。
- 保存 client_id 和 client_secret。通过您喜欢的任何环境变量方法使您的 Node 应用程序可以访问这些。
- 创建一个单独的脚本,专门用于通过 YouTube Data API v3 OAuth 获取 refresh_token
import { google } from 'googleapis';
import prompts from 'prompts';
console.log("about to execute oauth");
const yt_client_id = process.env.YOUTUBE_CLIENT_ID;
const yt_client_secret = process.env.YOUTUBE_CLIENT_SECRET;
const oauthClient = new google.auth.OAuth2({
clientId: yt_client_id,
clientSecret: yt_client_secret,
redirectUri: 'http://localhost'
});
const authUrl = oauthClient.generateAuthUrl({
access_type: 'offline', //gives you the refresh_token
scope: 'https://www.googleapis.com/auth/youtube.readonly'
});
const codeUrl = await prompts({
type: 'text',
name: 'codeURl',
message: `Please go to \n\n${authUrl}\n\nand paste in resulting localhost uri`
});
const decodedUrl = decodeURIComponent(codeUrl.codeURl);
const code = decodedUrl.split('?code=')[1].split("&scope=")[0];
const token = (await oauthClient.getToken(code)).tokens;
const yt_refresh_token = token.refresh_token;
console.log(`Please save this value into the YOUTUBE_REFRESH_TOKEN env variable for future runs: ${yt_refresh_token}`);
await prompts({
type: 'text',
name: 'blank',
message: 'Hit enter to exit:'
});
process.exit(0);
将刷新令牌保存在另一个环境变量中,您的主数据获取脚本可以访问该变量。像这样使用它:
import { google } from 'googleapis';
console.log("Beginning youtubeIndexer. Checking for valid oauth.");
const yt_refresh_token = process.env.YOUTUBE_REFRESH_TOKEN;
const yt_client_id = process.env.YOUTUBE_CLIENT_ID;
const yt_client_secret = process.env.YOUTUBE_CLIENT_SECRET;
const yt_channel_id = process.env.YOUTUBE_CHANNEL_ID;
const oauthClient = new google.auth.OAuth2({
clientId: yt_client_id,
clientSecret: yt_client_secret,
redirectUri: 'http://localhost'
});
oauthClient.setCredentials({
refresh_token: yt_refresh_token
});
const youtube = google.youtube("v3");
const channelResult = await youtube.channels.list({
auth: oauthClient,
part: ['snippet', 'contentDetails'],
id: [yt_channel_id]
});
let nextPageToken = undefined;
let videosFetched = 0;
do {
const videosResult = await youtube.playlistItems.list({
auth: oauthClient,
maxResults: 50,
pageToken: nextPageToken,
part: ['snippet', 'status'],
playlistId: channelResult.data.items[0].contentDetails.relatedPlaylists.uploads
});
videosFetched += videosResult.data.items.length;
nextPageToken = videosResult.data.nextPageToken;
videosResult.data.items.map((video, index) => {
//process the files as you need to.
});
} while (nextPageToken);
- 最后一个 .map() 函数,标有“根据需要处理文件”注释,将接收频道中的每个视频,无论是公开的、未列出的还是私有的。
注意:我还不知道给定的 refresh_token 会持续多久,但假设您经常需要再次运行第一个脚本并通过第二个脚本的环境变量更新使用的 refresh_token。
推荐阅读
- c# - 当前时区为 UTC 时,TimeZoneInfo.GetSystemTimeZones 不包含 TimeZoneInfo.Local
- rest - .NET Core 3.1 为我的 Intranet REST 端点添加安全性,针对 Windows 服务帐户/Active Directory 进行身份验证
- java - 在后端重新验证数据?
- angular - Firestore SnapshotChanges - 监听新文档
- python - 重命名 pdf 重命名 pdf 文件及其文本内容在特定位置
- javascript - searchItems 随机中断
- r - 扫描 R 的更快版本
- javascript - TypeScript:这个变量声明语法是什么意思?
- javascript - 在编译时检测不支持的正则表达式功能
- reactjs - 点击几下后分页项返回未定义