💬

Nodeで公式API使わずYoutubeLiveのチャットを取得するやつv2を公開した

2021/12/25に公開

配信のチャットをハックしたい!

突然ですが皆さんはYouTubeの配信ってやりますか?
私は配信者ですがよくやります

配信といえばリスナーのチャットがあるわけですが
そのチャットデータを簡単にデータ取れたら視聴者参加企画とか特殊なチャット表示とか
色々できて楽しそうだなぁって思いませんか?
私は思いました

そこで以前npmにYouTube公式APIを使わないでチャットを取得するやつを公開しましたが
今回バージョン2として作り直したので紹介します

作ったもの

https://www.npmjs.com/package/youtube-chat
https://github.com/LinaTsukusu/youtube-chat

使い方

README見ればだいたい分かると思いますが簡単に解説します

Getting started

まぁいつもの感じです

  1. インストール

    npm i youtube-chat
    # OR
    yarn add youtube-chat
    
  2. インポート

  • JavaScript
    const { LiveChat } = require("youtube-chat")
    
  • TypeScript or ESM
    import { LiveChat } from "youtube-chat"
    

チャット取得

  • EventEmitterベースになっています
// チャンネルIDから配信中のチャット欄を取得
// 配信IDは毎度変わるのでこちらが推奨
const liveChat = new LiveChat({channelId: "CHANNEL_ID_HERE"})

// 配信IDから特定の配信のチャット欄を取得
// まだアーカイブ対応とかしてないし多分使いにくい
const liveChat = new LiveChat({liveId: "LIVE_ID_HERE"})

// チャットの取得開始時に発火するイベント
liveChat.on("start", (liveId) => {
  /* Your code here! */
})

// チャット取得終了時に発火するイベント
// エラーで終了する場合も発火する
liveChat.on("end", (reason) => {
  /* Your code here! */
})

// メインです
// チャット1件ごとに発火される
liveChat.on("chat", (chatItem) => {
  /* Your code here! */
})

// エラー発生時に発火
// EventEmitterの仕様でこれがcatchの役割なので書いていないとエラー時に停止する
liveChat.on("error", (err) => {
  /* Your code here! */
})

// チャット取得開始 動いている間はプログラムが終了しない
// 一応asyncで開始したかどうかbooleanを返す
liveChat.start()


// 取得を停止
liveChat.stop()

取得データの型

interface ChatItem {
   author: {
      name: string
      thumbnail?: ImageItem
      channelId: string
      badge?: {             // メンバーバッジ詳細
         thumbnail: ImageItem
         label: string
      }
   }
   message: MessageItem[]   // 配列なので注意
   superchat?: {
      amount: string
      color: string
      sticker?: ImageItem
   }
   isMembership: boolean    // メンバーか
   isVerified: boolean      // 認証アカウントか
   isOwner: boolean         // 配信者本人か
   isModerator: boolean     // モデレータ(スパナ)か
   timestamp: Date
}

type MessageItem = { text: string } | EmojiItem

interface ImageItem {
  url: string
  alt: string
}

interface EmojiItem extends ImageItem {
  emojiText: string
  isCustomEmoji: boolean
}
  • messageは文字列ではなく配列で来ているため注意
    • カスタム絵文字等の対応でこうなっているらしい
    • 配列の中身は普通の文字列かEmojiItem型
  • スパチャの場合は額と表示色を取得できる

使用例

  • エアスパチャ
    • チャットを監視して特定のコマンド文字列があったら処理とかできる
    • これは古いバージョンのものだが
      チャットでコマンドを打つと配信画面上にスパチャと同じアラートを表示できる
  • ニコ生風チャット表示
  • コメビュ作成
    • チャット文字列だけでなくユーザー情報なども取得しているのでコメビュとかも作れる
  • FreeTube
    • この記事書いていて初めて気づいたがこのスターが5kくらいあるプロジェクトに使われているらしい
    • どこで使われているのかは知らない

なぜ公式APIを使わないの?

公式API無料なんだから使えば良くない?

とか思って使ってみましたが
おぉ、なんとることか😲
YouTubeDataAPIは1日あたりの使用量が決められていて1日12時間とか配信してたら
いくら節約して使っても余裕で上限オーバーだ
上限を増やしたりもできるが人によってはもっと配信したり他人のチャット取得したりしそうだしあんまり期待できなそう
っていうかYoutubeのチャットなんて視聴者全員ポーリングしてるんだからこれ使えばいいじゃん!

という感じで作りました
配信者がよく使うコメビュもこの方式だったし(普通の配信主がAPI_KEYわざわざ取らないよね)

Deno対応したい

🌧🦕🌧
skypackとかがあるのでせっかくだからDenoから使えるようにしたい

  • axiosだと現状使えないのでkyとか派生のuniverse版とか使いたい
  • これ系のモジュールが全部ESM化してたので誰でも使いやすくCJSのままだがESM版を作ったほうが良いかもしれない

良い解決策が思いつく方はぜひここにお願いします🙏

プルリク歓迎

V2にする際にレポジトリをキレイに使用ということでプルリクしやすくしました
Issueもプルリクも大歓迎ですので機会があればお願いします🙇‍♀️

Discussion