YoutubeDataAPIの叩きかた

この記事はMDC [Advent Calendar 2020](https://qiita.com/advent-calendar/2020/mdc) 12日目の記事です。

## はじめに

唐突なんですが学生の頃から[VTuber](https://ja.wikipedia.org/wiki/%E3%83%90%E3%83%BC%E3%83%81%E3%83%A3%E3%83%ABYouTuber)が好きだったんですよね。
追い始めて2~3年ですが今では個人勢から企業勢まで幅広く1万人以上もいるので中々追うのが大変だったりします。

ちょうど手頃なテーマだったのでどうせ何かアウトプットするなら自分で使うものがいいなと思い知識整理の意味も込めてGoogleカレンダーライクに配信スケジュールを見ることができるWebアプリを作ってみました。

こんな感じです。

![app-gif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137875/6e14feb9-5271-e156-7ec7-085f9c363587.gif)

構成はざっくりこんな感じです。

![app-image.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137875/d31ec4d6-1273-8bbe-f465-c45e54268552.jpeg)

今回は日次で新規の配信情報取得して今回はYouTube Data API v3で配信情報を取得するところをやっていきます。
（Webアプリの話は今回出てこないです。）

## APIキーの発行

APIキーは[この記事](https://qiita.com/iroiro_bot/items/1016a6a439dfb8d21eca)など参考に割とさっくり作れます。
特に迷うようなところもないです。

## 配信情報の取得

[このAPI](https://developers.google.com/youtube/v3/docs/search/list?hl=ja)を使います。
↓のようにチャンネルIDをキーに動画情報を取得します。APIキーは先ほど取得したもの、チャンネルIDは取得対象のチャンネルに飛んだ際のURLの末尾です（`https://www.youtube.com/channel/XXXXXXXXXXXXXXXXX`）。
（チャンネルIDはWebから月次でスクレイピングして収集しています。）

```
https://www.googleapis.com/youtube/v3/search?key=[APIキー]&maxResults=50&order=date&eventType=upcoming&part=snippet&channelId=[チャンネルID
]&type=video
```

その他設定しているパラメーターは以下です。

|param|設定値|説明|
|:--|:--|:--|
|part|snippet|必須パラメーターです。リソースを返すプロパティのグループの識別子をカンマ区切りで指定します。 APIによってパラメータに指定可能な設定値は異なりますが動画情報取得する場合はsnippetです。|
|maxResults|50|取得件数です(0~50)。配信予定が50以上もある配信者はいませんが最大値に設定しています。|
|order|date|ソート順です。dateだと配信予定作成した順になります。（※配信日順ではない）|
|eventType|upcoming|未配信の配信情報だけを取得します。過去の配信を取得したい場合はcompletedを設定します。|

親分ことキズナアイを対象に叩いた結果です。

``` json:api-response
{
  "kind": "youtube#searchListResponse",
  "etag": "MYp0wZDNVJAIdaE3ITKPnex7B0Y",
  "regionCode": "JP",
  "pageInfo": {
    "totalResults": 1,
    "resultsPerPage": 50
  },
  "items": [
    {
      "kind": "youtube#searchResult",
      "etag": "JArsc3kOYjrezOyqVADhFVi8VO0",
      "id": {
        "kind": "youtube#video",
        "videoId": "et_0xOzrKaE"
      },
      "snippet": {
        "publishedAt": "2020-11-30T15:38:04Z",
        "channelId": "UC4YaOt1yT-ZeyB0OmxHgolA",
        "title": "Kizuna AI 2nd Live “hello, world 2020”",
        "description": "12月29日(火)20時～スタート！   https://2020hello.world/ 【INFORMATION】 Title：Kizuna AI 2nd LIVE \"hello, world 2020\" Date：2020 / 12 / 29 (TUE) 20:00 JST ...",
        "thumbnails": {
          "default": {
            "url": "https://i.ytimg.com/vi/et_0xOzrKaE/default_live.jpg",
            "width": 120,
            "height": 90
          },
          "medium": {
            "url": "https://i.ytimg.com/vi/et_0xOzrKaE/mqdefault_live.jpg",
            "width": 320,
            "height": 180
          },
          "high": {
            "url": "https://i.ytimg.com/vi/et_0xOzrKaE/hqdefault_live.jpg",
            "width": 480,
            "height": 360
          }
        },
        "channelTitle": "A.I.Channel",
        "liveBroadcastContent": "upcoming",
        "publishTime": "2020-11-30T15:38:04Z"
      }
    }
  ]
}
```

## 配信情報詳細の取得

カレンダー作成する上で配信日時は必須の情報なのですが、上記の手段で入手できる情報が「配信予定を作成した日時」（＝所謂枠を取った日時）になります。なので、 今度は[こちらのAPI](https://developers.google.com/youtube/v3/docs/videos/list?hl=ja)で動画IDをキーに配信の詳細情報を取得します。

```
https://www.googleapis.com/youtube/v3/videos?part=liveStreamingDetails&key=[APIキー]&id=[動画ID]
```

設定しているパラメーターは以下です。

|param|設定値|説明|
|:--|:--|:--|
|part|liveStreamingDetails|必須パラメーターです。リソースを返すプロパティのグループの識別子をカンマ区切りで指定します。 APIによってパラメータに指定可能な設定値は異なりますが配信情報詳細を取得する場合はliveStreamingDetailsです。|

以下のようにレスポンスが返ってきます。
今度は配信開始時刻「scheduledStartTime」が取得できています。
これでカレンダーとして表現するための情報が一通りそろったのでDynamoDBに蓄積していきます。

``` json:api-response
{
  "kind": "youtube#videoListResponse",
  "etag": "hIVWKxNM54fdichRnB1jBvlY3Fw",
  "items": [
    {
      "kind": "youtube#video",
      "etag": "dh6a7ZnF-WK1gHH99Bvp3x69R54",
      "id": "et_0xOzrKaE",
      "liveStreamingDetails": {
        "scheduledStartTime": "2020-12-29T11:00:00Z",
        "activeLiveChatId": "Cg0KC2V0XzB4T3pyS2FFKicKGFVDNFlhT3QxeVQtWmV5QjBPbXhIZ29sQRILZXRfMHhPenJLYUU"
      }
    }
  ],
  "pageInfo": {
    "totalResults": 1,
    "resultsPerPage": 1
  }
}
```

やりたかった目的はここまでで達成することができました！

## おわりに

YouTubeDataAPIは叩く度に割り当てが消費されていき、無料枠だとリクエスト上限数がなかなか厳しかったです。
無料枠超えちゃうと`quotaExceeded`（＝叩きすぎ）と怒られその日はリクエストしてもずっとこのエラーが出ます。。。（0時リセット）

そのうちスクレイピングでデビューした新人VTuber探したりReact＋Reduxでフォルダ構成どうしようとか悩んだところかも記事にしたいです。