misskeyにシェアするChrome拡張を作ってみた

twitterでシェアするボタンは多くのサイトにあるが、[misskey.io](https://misskey.io)用のはほぼ無いので、
手軽にシェアできるようChrome拡張を作ってみた。

![help1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372771/80ae7268-129d-d257-9af9-30fee6cdee45.png)

同様のものはすでに[Twishare to Misskey](https://chrome.google.com/webstore/detail/twishare-to-misskey/fbaifpppndnlbbjcbjdfgbdkoibnipjb/related?hl=ja)というのがストアにあったが、セキュリティ的に権限を必要最低限に抑えたいというのと、画面内にボタンを常時表示させとくのはちょっと気になるので別途作ることにした。

Chrome拡張は以前から気になってはいたが、まじめに作ったことがなかったので色々と調べるところから。

## 開発準備

### 環境

* Windows 11
* vscode

### リポジトリ

https://github.com/betarium/share2misskey-io

### 仕様

misskeyの仕様で（twitterと同様に） https://misskey.io/share?text=hoge のようなURLでアクセスすると共有ページが表示され、メッセージを投稿できる。
この機能を利用するとして、あとはページタイトルとURLを取得して画面遷移できれば実現できそうである。

Chrome拡張の実行タイミングはページ表示時やボタンを押した時などがあるが、わかりやすく、かつセキュリティ的に安全そうなのはボタンを押した時に実行するタイプなのでこれで実装してみる。

## 開発

とりあえず`manifest.json`とHTMLとJavaScriptファイルがあれば動作はするらしい。
`extension`フォルダを作成し、その中にファイルを作成する。
`jquery-3.7.0.min.js`はjQuery公式からダウンロードして保存する。

```
+extension
 |-manifest.json
 |-popup.html
 |-jquery-3.7.0.min.js
 |-popup.js
```

### manifest.json
最低限必要な記述は以下になる。
`action/default_popup`で指定したHTMLファイルが、拡張機能を実行したときに表示される。
JavaScriptファイルはフォルダ内にあればよく、`manifest.json`で個別に指定する必要はないらしい。

```manifest.json
{
    "name": "Share2misskey.io",
    "version": "0.2",
    "manifest_version": 3,
    "action": {
        "default_popup": "popup.html"
    }
}
```

### popup.html
HTMLの記述は普通のWebページと大差ない。

```popup.html
<html>

<body>
    <h1>Share to misskey.io</h1>
    <div>
        <textarea id="message"></textarea>
    </div>
    <div id="button-area">
        <button id="close">Close</button>
        <button id="share">Share</button>
    </div>
</body>
<script src="jquery-3.7.0.min.js"></script>
<script src="popup.js"></script>

</html>
```

jQueryなどJavaScriptを使う場合はフォルダに入れておけばよい。`script`タグでJavaScriptファイル名（ディレクトリなし）を指定すれば読み込んでくれる。

### popup.js

JavaScriptファイルも普通のWebページと変わらず記述できる。
shareボタンをクリックしたら、`window.open`で新しいページを開き、misskeyの共有ページを開く。
jQuery書くのも久しぶりなので少し思い出すのに時間がかかった。

```popup.js
$(function () {
    (async () => {
        $("#message").val("hoge");
    })()

    $("#share").on("click", () => {
        const message = $("#message").val();
        window.open("https://misskey.io/share?text=" + encodeURIComponent(message), "_blank");
    })

    $("#close").on("click", () => {
        window.close();
    })
});
```

ここまででとりあえず画面表示するだけの拡張機能は作成できる。

Chromeの拡張機能のページを開き、デベロッパー モードをオンにした後、一度拡張機能のページをリロードする。
再度Chromeの拡張機能のページを開き、`extension`フォルダをドラッグアンドドロップで放り込むと拡張機能が追加される。
（もしくは、パッケージ化されてない拡張機能を読み込むで`extension`フォルダを指定する）

### ページタイトルとURL取得

タブの情報にアクセスするには`chrome.tabs`で提供されるAPIを使用する。
一部のAPIは`manifest.json`で`permissions`を指定しないと使用できない。今回はタブの情報取得のため`activeTab`と、設定フラグの保存のため`storage`を指定する。

```manifest.json
    "permissions": [
        "activeTab",
        "storage"
    ],
```

開いてるタブ以外へのアクセス等は別途権限が必要となるようなので、
`chrome.tabs`からタブを取得する際に`active: true`を指定する。

```popup.js
    const queryOptions = { active: true, currentWindow: true };
    const [tab] = await chrome.tabs.query(queryOptions);
```

タブからはタイトルとURLがそれぞれ`title`, `utl`で取得できる。
取得した値はmessageに設定する。

```popup.js
    const message = tab.title + " - " + tab.url
    $("#message").val(message);
```

あとはCSSで見た目を整えたり、アイコンや説明を追加したり、オプションページを追加して完成である。

## 配布・インストール

作成した拡張機能はchromeの拡張機能のページから`拡張機能をパッケージ`でパッケージ化(.crxファイルに)できるのだが、このファイルを配布してもストア経由でないと実行できないらしい。

ストアに登録するまでのものでもないので、とりあえずフォルダごとzipで配布することにした。
インストール手順は開発時と同じくである。

**ダウンロード** 
https://github.com/betarium/share2misskey-io/releases/download/0.2/share2misskey-io-0.2.zip

1. Chromeの拡張機能のページを開き、デベロッパー モードをオンにした後、一度拡張機能のページをリロードする。
2. zipファイルを展開したあとに、extensionsフォルダを拡張機能のページにドラッグする。
3. お好みで、拡張機能のボタンから固定に設定する。