YouTubeの統計情報を自動的に収集するツールを出品しました。



出品したツールを実装したときの知見を記録します。
これを見て、自分でGASを実装できちゃう方は、商品を買わなくてもいいですね(笑)
でも、もしよければ買ってください(宣伝)
以下は、公式のドキュメントです。

YouTube Data APIについての簡単な解説
GASで利用する際には、YouTube Data APIを利用するための「サービス」を追加する必要があります。
サービスを追加すると、以下のような機能を利用することができます。(主要なものだけ抜粋です。)
チャンネルの一覧を取得
以下のメソッドで取得できます。
YouTube.Channels.list(part: string[], optionalArgs: Object);
part
には、APIレスポンスに含める 1 つまたは複数の channel リソース プロパティを指定します。GASでは文字列の配列です。(以下の公式ドキュメントを参照)

optionalArgs
には色々とオプションを設定できますが、ここに取得したいチャンネルのIDを指定することになります。
再生リスト内の動画一覧を取得
以下のメソッドで取得できます。
YouTube.PlaylistItems.list(part: string[], optionalArgs: Object);
YouTubeチャンネルには、「アップロード済み」という再生リストが必ず存在するので、その再生リストのIDを optionalArgs
に指定してやれば、チャンネル内全ての動画を一覧で取得することができます。
しかしながら、 optionalArgs
の指定項目の中に maxResults
という項目があります。これは、一回のリクエストに対するレスポンスの取得上限数になるのですが、これは 50
が限界のようです。
なので、全ての動画一覧を取得するためには、このメソッドを全動画数分リクエストする必要があります。(詳しくはサンプルコードにて)

動画の詳細を取得
以下のメソッドで取得できます。
YouTube.Videos.list(part: string[], optionalArgs: Object);
list
というメソッド名ですが、 optionalArgs
で指定したIDの動画を取得することになります。
サンプル
お待たせしました。動画一覧を取得するサンプルコードです。
/**
* メイン関数
*/
function main() {
const channelIds = ['ID1', 'ID2'];
const channel = YouTube.Channels.list([
'snippet',
'contentDetails',
], {
'id': channelIds.join(',')
});
for (let i = 0, l = channel.items.length; i < l; i++) {
const item = channel.items[i];
const snippet = item.snippet;
const contentDetails = item.contentDetails;
const playlistId = contentDetails.relatedPlaylists.uploads;
const videoIds = getVideoIds(playlistId);
const videos = getVideos(sliceByNumber(videoIds, 50));
console.log(`チャンネル名: ${snippet.title}, 総動画数: ${videos.length}`);
}
}
/**
* チャンネル内の全ての動画のIDを取得する
*/
function getVideoIds(id, pageToken) {
const playlistItemsInfo = YouTube.PlaylistItems.list([
'contentDetails'
], {
'playlistId': id,
'maxResults': 50,
pageToken,
});
let videoIds = playlistItemsInfo.items.map(item => item.contentDetails.videoId);
const nextPageToken = playlistItemsInfo.nextPageToken;
if (nextPageToken) videoIds = [...videoIds, ...getVideoIds(id, nextPageToken)];
return videoIds;
}
/**
* チャンネル内の全ての動画の詳細を取得する
*/
function getVideos(ids) {
let videos = [];
for(let i = 0, l = ids.length; i < l; i++) {
const videoInfo = YouTube.Videos.list([
'snippet',
'statistics',
], {
'id': ids[i].join(','),
});
videos = [...videos, ...videoInfo.items];
}
return videos;
}
/**
* 第1引数のarrayを第2引数指定したnumberで区切って返す
*/
function sliceByNumber(array, number) {
const length = Math.ceil(array.length / number)
return new Array(length).fill().map((_, i) =>
array.slice(i * number, (i + 1) * number)
)
}
解説
ポイントに絞って解説します。
まず、「アップロード済みの動画」の再生リストのIDを取得する部分が下記です。
const playlistId = contentDetails.relatedPlaylists.uploads;
ここで取得したIDを、先程の YouTube.PlaylistItems.list()
の引数に指定してあげれば、アップロード済みの動画のIDを取得することができます。
ですが、前述したように、動画は50件ずつしか取得できないので、以下の部分で再帰処理を行っています。
if (nextPageToken) videoIds = [...videoIds, ...getVideoIds(id, nextPageToken)];
YouTube.PlaylistItems.list()
のレスポンスには、 nextPageToken
という情報が含まれており、それをYouTube.PlaylistItems.list()
の optionalArgs
に指定すると、「次の50件」を取得することができます。
レスポンスに含まれる nextPageToken
が undefined
になるまで、 YouTube.PlaylistItems.list()
の再帰処理を(nextPageToken
をリフレッシュしながら)行っている形になります。
終わりに
YouTube Data APIについてのご紹介でした。
今回のサンプルはQuotaを全く考えていないので、ご利用は計画的に。
最後に、出品したツール買ってください(宣伝)


