💬

YouTube Liveのチャット欄にNGワードを指定できるChromeExtension

2023/04/24に公開

はじめに

以前、YouTube Live およびそのアーカイブ動画のチャット欄に NG ワードを指定しフィルタリングする、とある Google Chrome Extension を愛用していましたが、最近使用できなくなってしまったので似たようなツールを自作しました。

https://chrome.google.com/webstore/detail/youtube-live-chat-blocker/pcpopnhheocmcboanpdlfebmlmbokppe

この記事はそのツールといくつかの技術的なポイントを紹介するものです。

「YouTube Live Chat Blocker」でできること

あらかじめ NG ワードとなる用語を登録しておくことで、一致したコメントを非表示にできるシンプルなものです。

非表示にする条件の指定方法には以下 3 つの方法を準備しています。

  • NG ワードが含まれるコメント(Contains)
  • NG ワードに完全一致するコメント(Equals)
  • 正規表現にマッチするコメント(Regular expression)

各条件は、拡張機能のアイコンをクリックすると表示されるポップアップ上で登録、削除できます。
また、各条件の全体有効化、無効化はトグルボタンによって制御できます。
いたってシンプルなツールです。

技術的なポイント

Manifest v3 への対応

Google は Chrome Extension の Manifest v2 を段階的に廃止しており受け入れも停止しています。
これから Chrome Extension を作成する場合は Manifest v3 を利用する必要があります。インターネット上で Chrome Extension の作り方を調べる際はバージョン情報を必ず確認しましょう。

v2 から v3 への移行に伴い本ツールで影響を受ける部分は、 manifest.json の書式で以下 2 点でした。

ホストへのアクセス権限の定義方法

v2 では permissions にホスト情報を指定できましたが、v3 では host_permissions という別のフィールドで指定します。

"permissions": ["storage"],
"host_permissions": ["https://www.youtube.com/*"],

https://developer.chrome.com/docs/extensions/migrating/manifest/#update-host-permissions

Background scripts の定義方法

v2 では “background”: “scripts” に対象の js ファイルを指定しましたが、v3 では、 "background": "service_worker" に指定します。

"background": {
  "service_worker": "background.js"
},

https://developer.chrome.com/docs/extensions/migrating/to-service-workers/

フレームへのスクリプト注入

本ツールのような、Web ページの DOM に対して操作を行うツールの場合、Content scripts を利用することになります。Content scripts は指定したページにスクリプトを注入して実行する方式です。

Youtube Live のページにも同様にスクリプトを注入しますが、チャット欄は別フレーム(ページとは別のURL)として ページに埋め込まれています。
この場合、 manifest.json には以下のように all_frames を指定し、ページ内のフレームもスクリプト注入の対象とする 必要があります。

そのうえで、チャット欄の URL をその対象として条件指定します。単純にそのページのアドレスバーに表示されている URL ではだめだということです。

"content_scripts": [
  {
    "all_frames": true,
    "matches": ["https://www.youtube.com/live_chat*"],
    "js": ["content_script.js"]
  }
]

popup 画面 ( Extension のアイコンをクリックした時に表示されるウィンドウ ) では NG ワードの登録を行います。NG ワードの登録が行われると即座にその NG ワード設定を適用させる必要があります。

そのために、 popup 側から Content scripts 側にデータの更新情報を渡す方法を考えなくてはなりません。

chrome.runtime API には異なるコンテキスト間でメッセージの受け渡しを行う機能 ( sendMessage()onMessage ) がありますが、本ツールでは、 chrome.storage の変更イベントで通知を受け取るようにしました。

https://developer.chrome.com/docs/extensions/reference/storage/#event-onChanged

NG ワードなどの設定は、Extension のストレージエリアに保存しています。
NG ワードが登録されるとそのストレージに保存を行うため、変更イベントが発生します。Content scripts 側でそのイベントを監視することで更新情報を受け取ることができ、すぐさまチャット欄に適用できます。

// popup.js
// NGワード情報のセット
chrome.storage.local.set({ ngWords: ngWords });
// content_script.js
// ストレージの更新イベント発生時
chrome.storage.onChanged.addListener((changes, namespace) => {
  // チャット欄への適用処理 ( changes に更新内容が含まれている )
});

チャット欄の監視

これは Extension 特有のものではないですが、DOM の監視についてです。
チャット欄への NG ワード適用は、ページ表示時にすでに表示されているコメントの他、あらたに追加されていくコメントにも行う必要があります。
監視対象の DOM が更新されたときに指定したコールバック関数を実行する機能が MutationObserver です。

https://developer.mozilla.org/ja/docs/Web/API/MutationObserver

const chatObserver = new MutationObserver(mutations => {
  // 変更イベント発生時処理
  mutations.forEach(mutation => {
    const chatNodes = [...mutation.addedNodes].filter(node => {
      return node.nodeType === Node.ELEMENT_NODE && node.classList.contains("yt-live-chat-item-list-renderer");
    });
    filter(chatNodes);
  });
});

// 監視の開始
chatObserver.observe(chatListNode, { childList: true, subtree: true });

ここではノードが更新されたときに実行する関数を new MutationObserver() の引数として指定し、新しい observer を生成しています。
この observer の対象となるノードを引数にし、 observe() メソッドにて監視を開始できます。
コールバック関数では、追加されたノード ( 複数の場合あり ) がチャットメッセージかどうかを判定し、そうである場合に NG 判定を行うようになっています。

おわりに

DOM 操作を行う類の Extenstion は処理対象の Web ページの仕様変更に弱くメンテナンスが大変です。
また、 Chrome Extension 側の API 強化も日々行われており、最新仕様を追うことも大変です。
ですが、 Internet Explorer のサポートが終了し Chrome Extension とも互換性のある Microsoft Edge の利用が多くなることを考えると、 Extension 開発の需要はより一層増えてきそうです。

コードは以下で公開しています。
https://github.com/sakmas/YouTubeLiveChatBlocker

Discussion