日々の業務をプチハック - Chrome Extension(拡張機能)を作ろう！

毎日の業務で、webブラウザから同じような操作してませんか？  
それ、`Chrome Extension` で自動化してみよう！  

`Chrome Extension` といいつつ、開発は `Microsoft Edge(chromium版)` でやっていきます。
(垂直タブ表示したいのでEdge使ってます)

**続編もあります**
[ホントは教えたくない、誰かがSlackにリアクションしたら便乗するChrome拡張を作る](./05d2d0805ee247f38826)
[ChromeExtensionでポップアップからコンテンツへメッセージ連動させる](./c200b6705d3626cc04f2)

## Chrome Extensionとは

ざっくりいうと、Chromeに拡張プログラムを入れて、既存のページを便利にする機能です(Edgeでも使えます)。

有名どころだと、Amazonで商品ごとの価格推移を教えてくれる[keepa](https://chrome.google.com/webstore/detail/keepa-amazon-price-tracke/neebplgakaahbhdphmkckjjcegoiijjo)なんかは、底値を確認するのにとてもお世話になっています。

## Chrome Extension で何ができるか？

ChromeExtensionを書くと

- Slack(web版)のリアクションボタンを自動で押す
- Salesf●rce 勤務時間の入力補助(時間合わせ、検算など)
- すぐ使いたいのにページ下部にあるボタンを移動

など、既存のwebアプリをちょっと便利にできます。

業務を自動化しよう、といいつつもこの記事では具体的な操作ターゲットとなるページ(webサイト)は決めていません。
いわゆる`Hello world` 的なものですが、これから Chrome Extension 始める人、またこれによって何ができるかの理解の助けになれば幸いです。

## ポップアップ画面の表示

まずは `hello world` 。
拡張機能のアイコンをクリックしたときに画面を表示させてみます。

画面はHTML、CSS、JavaScriptと、通常のwebサイトと同様に構成します。
まずは2つのファイルを用意します。

- manifest.json
- popup.html

### manifest.jsonの用意

作成する `Chrome Extension` のメタデータを記述します。
拡張機能名、ファイルの構成や動作対象のURL、リソースへのアクセス許可などを記載していきます。

```json:manifest.json
{
  "manifest_version": 3,
  "name": "ez-hacking",
  "description": "chrome拡張のテスト",
  "version": "0.0.1",
  "permissions": ["activeTab", "scripting"],
  "action": {
    "matches": ["https://www.google.com/"],
    "default_popup": "popup.html"
  }
}
```

`action.matches` で動作させたいURLを指定します。
今回は Googleのトップページのみで実行させます(`https://www.google.com/*` のようにワイルドカード指定することもできます)。 
ポップアップ表示させたいファイルを `action.default_popup` に指定します。
`name` に指定した `ez-hacking` が今回のアプリ名になります。

### popup.htmlの用意

まずは `hello world` なので、何もせずに表示するだけのHTMLファイルを用意します。

```html:popup.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>chrome拡張サンプル</title>
</head>
<body>
    <h1>hello world!</h1>
</body>
</html>
```

## 拡張機能として登録する

早速作った Chrome Extension をブラウザに登録しましょう。
`Chrome`または`Edge`の右上から、ジグソーパズルのピースのような「拡張機能」アイコンから、「拡張機能の管理」をクリック。  

![open-ext-management.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3104999/87dfbfaa-6c8a-9379-ba41-fa01d17fdbb0.png)


管理画面で、「開発者モード」を有効にします(chromeでは画面右上の「デベロッパーモード」)。  

![turn_on_devmode.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3104999/dd6ecd66-f8f9-a4eb-a938-c52f3054f607.png)


「展開して読み込み」(chromeでは「パッケージ化されていない拡張機能を読み込む」)から、先程のファイルが保存されているディレクトリを指定します。 
 
![read_folder.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3104999/38331f4c-f0a2-7c5e-08f2-3ce1587a721a.png)


拡張機能に追加されているので、アイマークアイコンをクリックして `ez-hacking` を表示状態にします。  
![turn-on-visible.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3104999/34aee87e-49eb-62ad-0080-415191501678.png)

追加されたアイコンをクリックすると、作成したポップアップ画面が表示されます！  

![hello-world.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3104999/287d113d-1961-6038-9672-38e9b023de9a.png)

コレだけだとなんになるの？って感じですが、実装を進めるとコンテンツ(操作対象となる画面側)に渡すためのパラメータなどをこちらで設定・管理できるようになります。
こういう管理画面を既存ページにスクリプトから埋め込むのは大変なので、このように自由に作成できるポップアップを使います。
(ポップアップとコンテンツの連携方法については別記事で)

※素のHTMLで記述していますが、React/Vue/Svelteなどで作成してもOK

## 画面操作

ポップアップ画面が作成できましたが、これらは表示されているコンテンツ(画面)とは別の領域で動作しています。  
コンテンツとポップアップではまだ連動されていないので、お互いに操作することはできません。

### コンテンツ(画面)側にスクリプトを読み込ませる

既存コンテンツを操作するには、コンテンツ側に、ポップアップとは別のスクリプトを読みませる必要があります。  
`background.js`を新規作成し、`manifest.json`に追記します。

### manifest.json の修正

コンテンツ操作のため、 マニフェストファイルの `content_scripts` に作成したJSファイルを追記します。

```diff_json:manifest.json
{
  "manifest_version": 3,
  "name": "ez-hacking",
  "description": "chrome拡張のテスト",
  "version": "0.0.1",
  "permissions": ["activeTab", "scripting"],
  "action": {
    "matches": ["https://www.google.com/"],
    "default_popup": "popup.html"
  },
+  "content_scripts": [
+    {
+      "run_at": "document_end",
+      "matches": ["https://www.google.com/"],
+      "all_frames": true,
+      "js": ["background.js"]
+    }
+  ]
}
```

### background.js の作成

読み込まれたことを確認するだけの、シンプルなJavaScriptファイルを用意します。

```javascript:background.js
alert('hello world')
```


### 更新したソースを再読み込み

ファイルを保存したら、拡張管理画面から「再読み込み」してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3104999/6b7c43ac-b6e4-6ab5-af38-1fd92178347b.png)

### 画面表示の確認

<https://www.google.com/> から、スクリプトの動作確認をします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3104999/893e8ae2-f41b-63d4-e477-d023d277fa3a.png)

アラートダイアログが表示されました！

## 次回、ポップアップとコンテンツの通信

これでポップアップ、コンテンツと両方で拡張機能を実行することができました。
しかし、まだバラバラで動作しているのでポップアップとコンテンツを連動させることができません。

連動については[ChromeExtensionでポップアップからコンテンツへメッセージ連動させる](./c200b6705d3626cc04f2)に続きます！

**続編もどうぞ**

- [ChromeExtensionでポップアップからコンテンツへメッセージ連動させる](./c200b6705d3626cc04f2)
- [ホントは教えたくない、誰かがSlackにリアクションしたら便乗するChrome拡張を作る](./05d2d0805ee247f38826)