Hajimeの妄言とTechの部屋

このブログでは、テック系の話や、ドキュメントに関する話などをエンジニアが「こんな感じに使うとええんじゃね?」ということを書き連ねるブログです。

Google Meetでコメントをニコニコ動画っぽく流すGoogle Chrome Extensionを改造してみた

はじめに

昨今、リモートワークが増えweb会議をする方が増えているかと思います。
かくいう私も同様にCovid-19の影響で2月頃からほぼ自宅リモート業務を進めています。

弊社のめちゃめちゃ早かった対応をまとめたブログはこちら↓

tech-blog.abeja.asia

Google Meetを使い始めたとき、単純に
「コメント見づらぃ、つらぃ」
と思っていました。
そんなとき見つけたのがこのTweetです。

見つけたときは「これだ!!」と思い、Githubリポジトリ*1を探し出し、早速コードを拝見しました。

謝辞

大本のChrome Extensionを考案&作成していただいた、ろぬ (@Yeq6N)様*2
素晴らしいアイディアと該当リポジトリを公開いただきありがとうございます。
この場をお借りしてお礼申し上げます。

作ったもの

f:id:DTM3110:20201003235719p:plain

NicoNicoStyle4MeetChromeExtension*3

動作イメージ

IMG

環境への追加方法

  1. NicoNicoStyle4MeetChromeExtensionへアクセス
  2. CODE ボタンから Download ZIP し、任意の場所にZIPファイルを解凍し該当ファイルを取得する
  3. Chrome拡張機能ページにアクセス
  4. デベロッパーモードを有効化し、 パッケージ化されていない拡張機能を読み込む で、解凍したフォルダを指定する
  5. ツールバーにあるアイコンからActivateを有効化する

追加した機能

  1. browser_action(拡張機能のアイコンをクリックしたら出てくるやつ)上で、コメントが流れるかどうかを切り替え機能を追加
  2. デフォルトを含めた7色を指定してコメントを流せるようなタグを作成 & 適応
  3. Small, Default, Largeの3パターンの文字サイズを指定するタグを作成 & 適応

システム構成

f:id:DTM3110:20201004014114p:plain

  1. 主要動作をするcontent_script(上図のscript.js)は、@ろぬ様のNicoStyleMeetの処理をほぼ踏襲
  2. content_scriptでは、Webページに紐づくlocalStorageに対して、この拡張機能が有効かどうかのフラグを格納
  3. browser_action(上図のsetting.js)はpopup.htmlのlocalStrageに対して、拡張機能の有効化フラグの状態を格納
    • popupを開いた際に、switchの状態を反映させておくため
  4. browser_actionのpopup.htmlではBootstrapを利用して有効化フラグの変更switchや、タグを挿入するボタンを追加
  5. setting.jsからscript.jsに有効化フラグや選択されたタグの情報を送信

ディレクトリ構成

NicoNicoStyle4MeetChromeExtension/
  ├ image/    # アイコンなどの画像ファイル
   |   ├ icon16.png      # 16x16
   |   ├ icon48.png      # 28x48
   |  └ icon128.png    # 128x128
  ├ script/
   |   ├ bootstrap.js     # Bootstrapのアコーディオンを使うためのjs
   |   ├ const.js            # クラス名の定数などを格納するjs
   |   ├ jquery.min.js    # jQueryを使うためのmin.js
   |   ├ script.js           # 実際に画面上にコメントを流す等の処理をするcontents_script
   |  └ setting.js         # ポップアップ(browser_action)での処理を実行するjs
  ├ style/
   |   ├ bootstrap.css    # Bootstrapを使うためのスタイルシート
   |  └ style.css            # コメントの色などを設定するスタイルシート
  ├ manifest.json    # Chrome Extensionでいちばん大事なやつ
 └ popup.html       # ポップアップ(browser_action)で表示するHTML

開発中のあれこれ

本当はやりたかったこと

f:id:DTM3110:20201004162137p:plain

本当は図のようにFirebaseのようなMbaaSと連携し、メッセージ内にタグを入れずにExtension内で設定情報とメッセージを一つのpayloadとして登録&Extension内で変更検知し、表示する。
というようなことをしたかったのですが、

  • meetってそういえばいろいろな人が使ってる
  • メッセージ内にクレデンシャル色の強い情報多い
  • そもそもメッセージの内容を外のDBに一時的にでも保存するのって怖い
  • Extensionでセキュリティを担保するのツライ

結局

メッセージ内にタグを埋め込んで、外部サービスを介さないように方針転換

工夫したこと

  1. const.jsを定義
    • jQueryでDOMを操作する際、idやclassの値を指定する必要がある
    • Google Meetでは↑これらの値が解読しづらくするために oIy2qc こんな感じになっている
    • const.jsに↑の値を定数として保存
    • manifest.jsonでconst.jsを先に宣言することで、 import などをしなくてもそのまま使える様になる(sample01参照)
  2. setting.jsからscript.jsへのデータ送信
    • chrome.tabs.sendMessage でsetting.jsからscript.jsにデータを送ることができる
    • データを受け取る際、chrome.runtime.onMessage.addListener のコールバック関数内でのみ取得可能
    • 送信するデータをObject型にしkeyの存在判定により、下記の処理をそれぞれ分けている(sample02参照)
      • 有効化フラグの変更・保存処理
      • 文字色変更タグ付与
      • 文字サイズ変更タグ付与
sample01
{
  "manifest_version": 2,
  ~~~~~~~
  "content_scripts": [
    {
      "js": [
        "./script/jquery.min.js",
        "./script/const.js",
        "./script/script.js"
      ],
      "css": ["./style/style.css"],
      "matches": ["https://meet.google.com/*"],
      "run_at": "document_start"
    }
  ],
  ~~~~~~~
}
sample02

payload

payload: {
  'active': true,
  'color': 'red',
  'size': 'l'
}
sample02

データ取得部

chrome.runtime.onMessage.addListener(function(request) {
  const keys = Object.keys(request)
  if (keys.includes('active')) {
    setActivateState(request.active)
  }
  if (keys.includes('color')) {
    setColorTag(request.color)
  }
  if (keys.includes('size')) {
    const size = request.size === 'large' ? 'l' : 's'
    setSizeTag(size)
  }
})

課題点

  1. Github Issues
  2. コメント入力フォームが展開されている状態じゃないとコメントが流れない
  3. 単純に重い
  4. セキュリティ問題解決できて、開発に時間割けるなら、リアルタイムDBとか使ってタグ自体がコメントスレッドに残らないようにしたい