作業中のネットサーフィンを防止するFirefoxのアドオンを作った

    こんにちは。

    作業中に調べものなんかしていると、ついついネットサーフィンを始めてしまう。。。

    という悩みをお持ちの方はいらっしゃいませんか?

    私です。

    今回は、ブラウザのアドオンを作って、作業中のネットサーフィンを防止することにしました。

    どんなアドオンを作るか

    自分はFirefoxをメインで使ってますので、Firefoxのアドオンを作ります。

    やりたいこと:

    ・URLのホワイトリストを作る
    ・ホワイトリスト以外のサイトを見ている時間を測る
    ・一定時間が経過したら、リダイレクト。

    なお、時間をリセットする条件はこんな感じ。

    ・ホワイトリスト内のサイトを閲覧
    ・一定時間ブラウザを操作していない(別に測っておく)

    アドオンのファイル構成

    ブラウザのアドオンは基本的にjavascriptで書きます。(Chromeも同じだと思います)

    どのアドオンにも必ず必要なのが、アドオンの設定を定義する「manifect.json」。

    そして、今回は、各ページに読み込ませて操作状況の取得やリダイレクトを行う「contents.js」と
    経過時間など共通の変数をもたせるための「background.js」が必要です。

    他にも、ホワイトリストを記載したcsvファイルや、リダイレクトさせるページが必要でしたので、
    最終的にファイル構成は次のようになりました。

    
    ├── icons
    │   └── border-48.png # 一覧で表示されるアイコン
    ├── img
    │   └── gg.png # リダイレクトページで表示させる画像
    ├── background.js
    ├── contents.js
    ├── index.html # リダイレクトページ
    ├── manifest.json
    └── whitelist.csv
    
    

    manifest.json

    定義ファイルです。
    中身はこんな感じ。

    
    {
    
      "manifest_version": 2,
      "name": "BlockSurfing",
      "version": "1.0",
     
      "description": "Protects you from unnessesary browsing.",
      
      "icons": {
        "48": "icons/border-48.png"
      },
    
      "permissions": [
        "webRequest",
        "<all_urls>"
      ],
    
      "content_scripts": [
        {
          "matches": ["<all_urls>"],
          "js": ["contents.js"]
        }
      ],
    
      "background": {
        "scripts": ["background.js"]
      }
    
    }
    
    

    詳細は省きますが、重要なのは「permissions」「contents_scripts」「background」の3つでした。

    permission…今回は、ページにリダイレクトさせるために「webRequest」そして全てのページを操作する必要があるので「<all_urls>」の権限をこのアドオンに持たせています。

    contents_scripts…各ページに読み込ませるjsを定義します。今回は、全てのページに読み込ませる必要があるので、ここでも「<all_urls>」としています。

    background…各ページの動作を統括するためのjsを定義します。このjsはブラウザ起動時に読み込まれ、閉じるまで存在し続けます。

    contents.jsの内容

    今回、contents.jsの役割は2つありました。

    ・ページを操作した時に、その情報をbackground.jsに送る。
    ・リダイレクトの命令をbackground.jsから受け取って、リダイレクトさせる。

    というのも、background.jsではページの具体的な操作は一切できないからです。
    ブラウザ内でのメッセージ送受信機能を使って実現します。

    ブラウザにメッセージを送る時はこんな感じ。
    ページのURLを送っています。

    
    addEventListener('click', report);
    addEventListener('keydown', report);
    addEventListener('scroll', report);
    
    function report() {
      browser.runtime.sendMessage({"url": location.href});
    }
    
    

    ※ページをクリックした時、キー操作を行った時、スクロールした時に送信しています。
    バッググラウンドで音楽を流している時やただ表示している場合なんかには動かないようにしました。

    受け取るにはこんな感じ。
    問答無用でリダイレクトさせています。

    
    browser.runtime.onMessage.addListener(function(message) {
      location.href = message.redirect;
    });
    
    

    ただ、jsを読み込んだ時点ではbrowserが初期化されていなかったのでどのタイミングでリスナーを
    追加すればいいかわからずハマりました。

    最終的に、メッセージを送信するときに一緒に追加するようにしたらなんとかなりました。

    
    var listen = null;
    function report() {
      if(listen == null) {
        browser.runtime.onMessage.addListener(listen = function(message) {
          location.href = message.redirect;
        });
      }
      browser.runtime.sendMessage({"url": location.href});
    }
    
    

    background.jsの内容

    今回、background.jsの役目はcontents.jsより多くて4つありました。

    ・ホワイトリストのcsvを読み込む。
    ・contents.jsからメッセージを受信する。
    ・時間を計測する。
    ・条件を満たしたとき、リダイレクトの命令をcontents.jsに送る。

    時間の計測とcsvの読み込みは特筆することはないので省略します。

    ただ、csvやリダイレクト先のページはアドオンの中に同梱してますので、
    URLを調べるために以下のようにしました。

    
    browser.extension.getURL("whitelist.csv")
    browser.extension.getURL("index.html")
    
    

    ちなみにbrowser.extension.getURL(“”)としても自動的にindex.htmlを表示してはくれなかったです。

    contents.jsとのやりとり

    contents.jsから連絡を受け取るときはこんな感じです。

    
    browser.runtime.onMessage.addListener(onMessage);
    
    function onMessage(message, sender) {
      //処理内容
    }
    
    

    messageにはbrowser.runtime.sendMessage()で送った内容、
    senderには送信元のページ情報が入っています。

    最終的に、送信元にリダイレクト命令を送る時はこうしました。

    
    browser.tabs.sendMessage(
      sender.tab.id,
      {"redirect": browser.extension.getURL("index.html")}
    );
    
    

    tabs.sendeMessageにはタブのIDを指定しなければいけないのですが、
    その調べ方がわからずハマりました。。がいろいろ調べた結果、
    onMessageから受け取ったsenderから、sender.tab.idでできました。

    アドオンの登録

    アドオンを使うには、Firefoxのサイトに登録する必要があります。

    ※手軽に使うにはデバッグモード(検索バーにabout:debuggingと入力)から追加できますが、ブラウザを閉じると解除されてしまうので、ずっと使い続けたい場合は登録する必要があります。

    Firefoxアカウントの作成 https://addons.mozilla.org/
    アドオンの登録 https://addons.mozilla.org/ja/developers/

    今回は自分だけで使うので「自分自身で。」を選択しました。
    他人に配付する場合は証明書が必要になります(限定公開も含む)

    登録は、zipしてアップロードするだけなので簡単ですが、
    フォルダに入れた状態でzipするとmanifest.jsonを見つけられないみたいです。
    manifest.jsonなどをフォルダに入れてない状態でzipしてください。

    登録が完了すると、xpiファイルをダウンロードできますので、それをFirefoxで開けばインストール完了です。

    使ってみよう

    さっそく、無関係なサイトにアクセスしまくって動作するか確認してみます。

    か、勘違いしないでよねっ、あくまでテストのためなんだからっ・・・・!

     

     

     

    とりあえずねとらぼでも読むか・・・・

    ルーツレポはいつも面白いなー

    ほうほう、なるほど・・・これはいい記事だなぁ~・・・

    ・・・・

    ・・・・

    ・・・・

    ・・・・

    ・・・・

    ・・・・

    ・・・・

    ・・・・

    あっ!!??

    うわぁーーーーーーー!!!

    まだ読んでたのにーーーーーーー!!!

    結果

    ちゃんとネットサーフィンが防止できることが確かめられました。

    今後

    現状、ホワイトリストの中身やタイムアウトの時間が固定になっているので、
    変更するための設定画面を用意する必要がある気がしてます。

    ただ、気軽に変更できるとネットサーフィンの危険が高まってしまうので、
    固定なら固定でいいような気もしています。

    では、みなさんも程よいネットサーフィン生活をお楽しみください!