Chrome拡張が簡単に作れて驚いた（ついでにバックエンドもつけた話）

いつもお世話になっている、Google Chromeですが[拡張機能](https://chrome.google.com/webstore/category/extensions)が豊富なのも魅力のひとつだと思います。
ぼんやりと「こんなのがあったらいいなぁ」というアイディアがいくつかあったのですが、[strapi](https://strapi.io/)を触る機会があったので、アイディアのうちの一つを形にしてみた時の記録です。

本稿のようなものであれば、バックエンド込みでもすごく簡単なので普段からHTMLやJSに慣れ親しんでいるフロントエンドエンジニアは皆さんやってみたらいいと思います。

2019/12/14追記：誰でも初められる[チュートリアル](https://qiita.com/teixan/items/9a684870a7e551412a05)書きました。すぐできる簡単な内容にしたので是非。

## 前提

ちなみに、まだ公開していませんので宣伝ではありません。手取り足取り的なチュートリアルでもないです。
「元エンジニアの現プランナー・ディレクターの僕でも作れました」という話で、どういう考えからものづくりをしたかが中心の話になります。

##  「そのページの情報がまだ役立つか、みんなの投票結果を表示する」拡張機能

### 当初のコンセプト
- 情報には消費期限があるが、情報ごとに期間がまちまち
- 公開・更新日時が新しいものであっても役立つ情報か、見てみるまで（試してみるまで）わからない
- 古いページでも役立つものはある
- ページ単位でstack overflowの **Up or Down** みたいなことができたら便利

形式的には[「はてなブックマーク」のChrome拡張](https://chrome.google.com/webstore/detail/%E3%81%AF%E3%81%A6%E3%81%AA%E3%83%96%E3%83%83%E3%82%AF%E3%83%9E%E3%83%BC%E3%82%AF/dnlfpnhinnjdgmjfpccajboogcjocdla?hl=ja)のブックマーク数部分だけ切り取ったようなものです。
はてブ自体がかなり長く続いているプラットフォームだということもあり、現時点で本当に役立つか怪しいものもブクマ数が多かったりします。

**「まだ役立つ情報」にはポジティブな、「もう使えない情報」にはネガティブな投票がはいり、それが可視化できるといいなぁ**といったところでした。

### 出来たもの「Still useful（仮）」
![still_ss_001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546514/87c89748-ac0e-ca97-fb01-2cc24c436fa4.jpeg)
- アイコンに現在のスコアが表示される（青・赤でバッジ表示）
- ポジティブ・ネガティブでアイコンが変わる（ポジティブ：青 / ネガティブ：赤 / 未投票：緑）
- ポップアップを開くと、ページタイトル・スコア・投票ボタンが表示される

## 拡張の本体自体はHTML(+CSS)+JS

作るのはいたって簡単で、以下のページを参考にするとすぐ出来ます。本当に普通のHTML。

[Chromeブラウザの拡張機能を作ってみたい初心者向けに開発方法を紹介！【サンプルあり】](https://qiita.com/guru_taka/items/37a90766f4f845e963e5)
[続・Chrome拡張を10分で作って公開する](https://qiita.com/yamamoto_hiroya/items/0f9f087a61a0ac88c7d3)

こういうチュートリアルには`Background.*` とか `content_scripts.*` とか `default_popup.*` とかがどっさり出てきますが、自分の必要なものだけ追加していくイメージが大事だと思います。

```text:ファイル構成
.
├── background
│   ├── background.html //バックグラウンド処理用なのでほぼ空
│   └── background.js   //バックグラウンドのタブ切り替え時の処理
├── icons
│   ├── icon-128.png
│   ├── icon-128_green.png
│   └── icon-128_red.png
├── imgs
│   ├── loading.svg
│   ├── new.svg
│   ├── thumb_down.svg
│   └── thumb_up.svg
├── jquery.min.js
├── manifest.json       //設定等を記述
└── popup
    ├── popup.html      //ポップアップの表示
    └── popup.js        //ポップアップの処理
```
当初はポップアップのみで完結する予定だったので、`popup.html + popup.js`のみでした。やはりアイコン切り替えも実装しちゃおうと`background.html + background.js`を追加、その都度`manifest.json`に追記、みたいな流れです。

とりあえず誰かの`manifest.json`の大事そうなところだけコピペ、そのフォルダごとChromeにて読み込むだけでお試しできます。圧縮の必要もないです。

![import.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546514/08d2e144-4874-a316-9ada-7ffa32a1f25f.jpeg)


`background.*`でタブ切替時にアイコンが切り替わって、アイコンがクリックされると`popup.*`にて表示・処理が行われます。中身はものすごく純粋なHTMLとJSで問題なく、深めていくと諸々制約があるようですが、今回はエラーに遭遇することもなくあっさり動きました。

困ったときは[公式](https://developer.chrome.com/extensions)か下記のページあたりを参考にするとなんとなく進められると思います。

[Chrome拡張でとっても役立つAPIのまとめ](https://qiita.com/Yuta_Fujiwara/items/daf41429f95caec82982)

## 投票データを管理

投票できるということはどこかでデータを蓄えて管理しなければならないので、所謂バックエンドが必要です。
少し前だったらAPIを扱えるCMSを、どこかに借りたサーバに構築して、DBを作って…という感じでしたが、今はサクッとAPIを作れるHeadlessCMSとやらを、これまたサクッとデプロイ・公開できるプラットフォームがあるという時代になったので早速使ってみました。

### CMSにはStrapiを採用してみた

strapiの選定理由
- とりあえずヘッドレスで十分
- 構築が簡単・早い
- APIがシンプル
- 興味

構築自体は本当に簡単です。とりあえず下記のクイックスタートガイドをお試しください。どれだけ簡単かわかると思います。
[Quick Start Guide | Strapi Documentation](https://strapi.io/documentation/3.0.0-beta.x/getting-started/quick-start.html)

今回のようなAPIを作る上ではメリットとなったシンプルさですが、業務で使う際には認証が必要になったりとカスタマイズが必要になり、デメリットになるかもしれません。その点、例えば、[contentful](https://www.contentful.com/)などではデフォルトで認証が必要な仕組みになっているようなので良いかもしれません。

> Any client requesting content from the CDA needs to provide an access token that has access to the environment you're requesting content from.
[Content Delivery API – Contentful](https://www.contentful.com/developers/docs/references/content-delivery-api/#/introduction/authentication)

### ホストにはHerokuを採用してみた

選定理由
- デプロイが楽
- 無料プランがある
- 興味

[Heroku cli](https://devcenter.heroku.com/articles/heroku-cli)が用意されており、また[Node.jsの自動ビルド](https://devcenter.heroku.com/articles/nodejs-support)に対応しているので、コミット->プッシュだけでガリガリ開発を進められるのは楽でした。

Gitを少しでも触ったことがあれば使えます。例えば変更を入れた際のコミットはこんな感じ。

```
git commit -am "update something"
git push heroku master
```
クライアントアプリを使ってても問題ないと思います。

静的なHTMLでもデプロイ可能なようなので、こちらにあるような流れで簡単にお試しできます。リアルマジで即公開できるので。
[Herokuを使って簡単にウェブページをインターネットで公開する方法](https://qiita.com/reoring/items/bca12aaa5f94b190a488)

### 結果

strapi+herokuのAPI構築はローカルでの構築・デプロイ・ビルドまで20分くらいでした。バックエンドはプログラムを1行も書いていないのでまぁ誰でも出来る内容です。

## まとめ
拡張からAPIを叩けることを確認でき、とりあえず動きました。
感覚的には、**ブックマークレットをガリガリ作るくらいなら拡張作っちゃってもいいかも**、くらいです。リサーチからここまで丸１日くらいだったので、案件の暇な日の研究テーマにもってこいなのではないでしょうか。

### （メモ）残タスク
- 認証の実装
- Google検索結果に表示
- 更新日時からの算出
- 時間が経つと投票が減っていく
- 見栄えを整える
- 公開する