こんにちは.
皆様, はてなブックマーク はお好きですか? 私は嫌いです.
はてなブックマーク経由で Twitter に共有されたリンクなどを踏むと, 直接目的のページへ飛ばしてくれない上に, 謎のおじさん達のブックマークコメント (ブコメ) が表示されて大変虚無です.
なので, はてなブックマークのブコメをスキップし, 直接目的のページへ飛べるようにする Chrome 拡張を作成しました.
No Hatena Bookmark - Chrome Web Store
sarisia/NoHatenaBookmark - GitHub
No Hatena Bookmark
その名の通り, はてなブックマークを見たくない人向けの Chrome 拡張機能です.
インストールするだけで, ブコメページへのアクセスを自動的に目的のページへリダイレクトします.
一応, “次の1回を無効化” や “ブラウザを再起動するまで無効化” の2つの無効化オプションもつけておきました. 自分ではテスト時以外には使いませんが…
開発
せっかくなので, 仕組みや Chrome 拡張の開発についてちょっとだけ書き残しておきたいと思います.
しくみ
やってることはあまりにも単純で, Chrome がはてなブックマークの URL へリクエストを送ろうとした際に, URL をゴニョゴニョして目的のページの URL を取り出し, リダイレクトしているだけです. 以下は詳細な流れです.
- ユーザがはてなブックマークの URL を踏む
- Chrome API のイベントが発火し, コールバックにはてなブックマークの URL が渡される
- コールバック内ではてなブックマークの URL を処理し, 目的のページの URL を取得し, コールバックの返り値として返す
- Chrome はコールバックの返り値により, ユーザのリクエストを目的のページへリダイレクトする
はてなブックマークの URL 形式
はてなブックマークは, ブコメページへの URL がブックマークされているページ (目的のページ) の URL を含んでいるため, この拡張機能は, はてブAPI 等への追加のリクエストなしにリダイレクト先を決定することができます.
ブコメページへの URL には様々な形式があり, また, それぞれの形式によりサーバのレスポンスも異なっているので, うまいことやっていく必要があります.
私がこれまでに見つけたのは以下の形式のものです. なお, サンプルの URL は example.com/hoge?query=fuga
を目的のページとしています:
-
https://b.hatena.ne.jp/entry?url=https://example.com/hoge?query=fuga
クエリパラメータ
url
として目的のページの URL を含んでいる形式です.url
の内容はパーセントエンコーディングされていたりされていなかったりしますが, どちらも正常に動きます.スキーマ (
http://
とかhttps://
) がないと400 Bad Request
が返ってきます. -
https://b.hatena.ne.jp/entry/s/example.com/hoge?query=fuga
entry
以降のパスパラメータとして URL を含んでいる形式です. スキーマによって/entry/example.com/...
だったり/entry/s/example.com/...
だったりします. -
https://b.hatena.ne.jp/entry/https://example.com/hoge?query=fuga
一番
意味不明ビビった形式です./entry/
以降に URL がそっくりそのまま入っています. パーセントエンコーディングされていたりされていなかったりします.アクセスすると, はてなブックマーク側で
/entry/s/example.com/...
形式のページへリダイレクトされるので, 拡張機能ではリダイレクトしていません.
これだけでも混沌としていますね. やりづらかったです.
これら URL 形式については特に公式のドキュメントがなかったので, 人力で適当に探した結果です. 漏れがあったら是非教えて下さい.
Chrome Extension API
Chrome には拡張機能の開発のための便利な JavaScript API が用意されています.
今回利用した chrome.webRequest
API は, Web リクエストのライフサイクルの各イベントに対してコールバックを登録し, Web リクエストを覗き見ることができます. また, 一部のイベントはコールバックの同期実行にも対応しているので, Web リクエストを覗き見ながら改変することもできます.
ドキュメント通りに書けば動いてくれる素直な API です. 便利ですね.
Chrome Web Store つらい問題
Chrome 拡張の開発はパワフルな API のおかげで非常に楽ですが, 成果物を Chrome Web Store に並べたいとなると途端につらいポイントが増えます.
Chrome Web Store は Chrome 拡張機能のマーケットプレイスです. Web Store に成果物を並べておけば, ユーザは拡張機能をワンクリックでインストールして利用できる他, 自動アップデートの面倒なども見てくれます. 拡張機能は積極的に Web Store に公開すべきでしょう.
一方で, ストアへの公開までの作業が思ったよりつらいです. 使っていて感じたつらいポイントをいくつか書き残しておきます:
-
各種イメージが必要
拡張機能を Web Store に並べるにあたり, いくつか必須のイメージが指定されています. 具体的には,
- ショップアイコン (拡張機能のアイコン)
- スクリーンショット (最低1枚)
は必須です. 私は Illustrator をカチカチして作成しました. 開発の中で一番時間がかかったかもしれない.
-
API を使う理由を逐一問われる
この拡張機能では, ユーザのリクエストを取得, 改変するために
webRequest
,webRequestBlocking
, また, コンテキストメニューに設定を追加するためのcontextMenus
権限を利用していますが, Chrome Web Store では, 審査のために, それぞれの権限が必要な理由を申告する必要があります.この場合は, 上記3つの権限 + ホスト権限の4つに対してそれぞれ理由を記載する必要があります. それぞれの理由は長文ではなく, 100文字程度の短い説明でも審査は通りましたが, 更に多くの権限を要求する複雑な拡張機能では気が狂いそうです.
また, “ホスト権限が必要な理由” に対しては, 「
webRequest
を利用するために必要ってドキュメントに書いてあるからだが…」としか言えず, なんだかなあ, という気持ちになります. -
CI/CD からの自動デプロイができない
ドキュメントを読んでも Developer Dashboard を探し回っても自動デプロイのエンドポイントがありません. せっかく CI を組んでいてもリリースの度に “アセットをダウンロードしてダッシュボードにアップロードして審査を請求して…” といった儀式が必要になります. せめてアップロードは自動化させてほしい.
おわりに
Chrome 拡張, 気軽にブラウザをいい感じに操れるので便利ですね. もっと積極的に書いていきたいと思います.
はてブ嫌いの方は是非 No Hatena Bookmark をどうぞ.