タイムライン投稿にYouTube動画検索連携機能を実装した

何をやったか

つぶやき投稿フォームから YouTube 動画を検索し、「視聴した動画」としてつぶやきに添付できる機能を追加した。

これまでは YouTube の URL をテキストに貼り付けると自動で動画プレーヤーが埋め込まれる機能があったが、今回はそれに加えて「どの動画を視聴したか」をメタデータとして保存・表示できる仕組みを作った。


なぜ作ったか

ゲーム情報・アニメ情報と同じように、「見た動画」をつぶやきに添付したいという需要があった。テキストに URL を貼るだけでも動画は埋め込まれるが、タイトルやチャンネル名の情報が失われてしまう。動画メタデータを保存することで、後から「何を視聴したのか」が一覧からも分かるようになる。


実装の全体像

1. データベースの拡張

既存の notes テーブルに youtube_info カラムを追加した。ゲーム情報・アニメ情報と同様に、JSON 文字列として動画メタデータを保存する。

保存するデータは以下の通り:

2. YouTube Data API v3 との連携

バックエンドで YouTube Data API v3 の検索エンドポイントを呼び出している。

GET https://www.googleapis.com/youtube/v3/search?part=snippet&q={query}&type=video&maxResults=5&key={YOUTUBE_API_KEY}

必要な環境変数:

YOUTUBE_API_KEY — Google Cloud Console で取得した YouTube Data API v3 の API キー。Cloudflare Pages の環境変数(シークレット)として設定する。

3. セキュリティ設計

セキュリティ上の考慮点:

入力値検証

認証

レスポンス整形

4. 投稿フォームへの UI 追加

既存のゲーム検索・アニメ検索パネルと同じスライドアップ方式でパネルを実装した。

ツールバーに「YT」ボタンを追加している。絵文字は使わず、シンプルなテキストにした。

5. タイムラインでの表示

既存の YouTube iframe 埋め込みロジックを拡張した。


詰まった点

サムネイル URL のドメイン検証

YouTube のサムネイル URL は i.ytimg.com から配信されるが、エッジケースとして yt3.ggpht.com(チャンネルアイコン等)も存在する。フロントエンドから来た URL を無制限に受け入れると SSRF 等のリスクがあるため、ドメインを明示的に許可リストで制限した。

watchUrl の生成

クライアント側で生成した watchUrl をそのまま DB に保存すると、意図しない URL が保存されるリスクがある(例えば javascript: スキーム)。そのため、DB に保存する際は常に videoId から https://www.youtube.com/watch?v={videoId} を生成し直している。


設定方法

YouTube 検索機能を有効にするには、以下の手順で API キーを設定する:

  1. Google Cloud Console にアクセスし、YouTube Data API v3 を有効にする
  2. API キーを発行する(IP 制限・リファラ制限を設定することを推奨)
  3. Cloudflare Pages の管理画面で、環境変数 YOUTUBE_API_KEY にキーを設定する
  4. API キーは Git リポジトリに含めない

学んだこと