Mastodon向け簡易シェアボタン

:::note alert
この記事の手法は2023年4月現在、使えなくなっています（Mastodon側での `registerProtocolHandler` の使用が無効化された）。関連issue:

* [Use web-based protocol handlers to make following across instances easier · Issue #19679 · mastodon/mastodon](https://github.com/mastodon/mastodon/issues/19679)
:::

# 背景

Twitter等のSNSは多くの場合、Webサイト構築者向けに「シェアボタン」や「フォローボタン」用のURLを用意している。

例えば、Twitterの場合はWebサイトに

```
https://twitter.com/intent/tweet?text=(内容)
```

という形式のリンクを貼れば、それが簡易的なシェアボタン（ツイートボタン）として機能する（[詳細](https://developer.twitter.com/en/docs/twitter-for-websites/tweet-button/guides/web-intent
)）。

例：

```html
<a href="https://twitter.com/intent/tweet?text=%E3%81%93%E3%82%93%E3%81%AB%E3%81%A1%E3%81%AF%E4%B8%96%E7%95%8C" target="_blank">「こんにちは世界」とツイートする</a>
```

<a href="https://twitter.com/intent/tweet?text=%E3%81%93%E3%82%93%E3%81%AB%E3%81%A1%E3%81%AF%E4%B8%96%E7%95%8C" target="_blank">「こんにちは世界」とツイートする</a>

Mastodon向けにもこのようなシェアボタンを設置できれば良いが、MastodonはインスタンスごとにURLが異なるため、普通にやると**特定のインスタンス用の**シェアボタンになってしまう。（例えば、Pixivには**Pawoo専用の**シェアボタンが設置されている）

一方、 [Mastoshare](https://mastoshare.net/) や [マストポータル](https://mastportal.info/share) 等のサービスは「**任意のインスタンス向けの**シェアボタン」を提供しているが、トゥートするには

* シェアボタン提供者が用意している「メジャーなインスタンスのリスト」から選ぶか、
* インスタンスのURLを手打ちする

必要があり、マイナーなインスタンスの利用者にとっては敷居が高い。

しかし、Mastodon v1.6.0以降では、**プロトコルハンドラー**を使うことにより

* 任意のインスタンス向けのシェアボタンを
* インスタンスのURLを手打ちさせることなく

実現できる。（ただし欠点として、2018年現在では対応ブラウザーが限定される。そのため記事のタイトルを「簡易」とした）

# （Webベースの）プロトコルハンドラー

（Webベースの）プロトコルハンドラーとは、 `mailto:` や `webcal:` のような `http(s):` 以外のプロトコルをWebアプリケーションが処理できるようにするためのWeb APIである。詳しくはMDNを参照：

- [Web-based protocol handlers - Web APIs | MDN](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/registerProtocolHandler/Web-based_protocol_handlers)
- [Navigator.registerProtocolHandler() - Web APIs | MDN](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/registerProtocolHandler)

現時点でChromeとFirefoxは対応しているが、SafariとEdgeは未対応のようだ。

このプロトコルハンドラーを使うと、「任意のインスタンス向けの」シェアボタンを次のような流れで実現できる：

1. Mastodonの各インスタンスは、JavaScriptで `navigator.registerProtocolHandler()` を呼び出すことにより、 `web+mastodon:` プロトコルを自身のURL（`https://example.com/intent?uri=%s`）に紐つける。
   この処理は、典型的にはそのインスタンスを最初に開いた際に行われる。ブラウザーによってはユーザーの明示的な操作を必要とする。
2. Webサイト構築者は、シェアボタンを `web+mastodon:` プロトコルのリンクとして設置する。
   例：`<a href="web+mastodon://share?text=...">Share with Mastodon</a>`
2. 閲覧者が `web+mastodon:` プロトコルのリンクをクリックする。
   ブラウザーは（必要なら選択のためのUIを表示して）登録済みのプロトコルハンドラーを呼び出す。
   閲覧者が複数のインスタンスを利用している場合、この段階でどのインスタンスにシェアするのかが決まる。
3. 1. で紐つけられたURL（`https://example.com/intent?uri=web%2Bmastodon%3A%2F%2Fshare%3Ftext%3D...`）が開かれる。後は、各インスタンスが、トゥートしたりフォローしたりするためのUIを提供する。

# `web+mastodon:` プロトコル

2018年8月現在の最新版（v2.4.3）で確認する限り、実装されているURLの形式は次の通りである：

```
web+mastodon://share?text=（内容）
web+mastodon://follow?uri=（ユーザー名とドメイン）
```

`text=` および `uri=` 以下の引数は当然URLエンコードしておく。

なお、 `（ユーザー名とドメイン）` が `acct:` から始まる場合、`acct:`は無視される。

URLの例：

```
web+mastodon://share?text=%E3%81%93%E3%82%93%E3%81%AB%E3%81%A1%E3%81%AF%E4%B8%96%E7%95%8C
web+mastodon://follow?uri=mod_poppo%40mstdn.jp
```

# ボタンの例とデモ

ただのハイパーリンクだと味気ないので、適当にCSSで見た目を整えよう。また、プロトコルハンドラーに非対応のブラウザーでボタンを表示しても仕方がないので、その場合はボタンを非表示とすると良いかもしれない。

例：

```html
<style type="text/css">
.mastodon-share-button {
  display: inline-block;
  vertical-align: middle;
  height: 20px;
  color: white;
  background-color: #49a0de;
  border-radius: 3px;
  text-decoration: none;
  font-size: 11px;
  padding: 0 8px 0 8px;
}
body.no-protocol-handlers .mastodon-share-button {
  display: none;
}
</style>
<a class="mastodon-share-button"
   target="_blank"
   rel="noopener noreferrer"
   href="web+mastodon://share?text=Mastodon%E5%90%91%E3%81%91%E7%B0%A1%E6%98%93%E3%82%B7%E3%82%A7%E3%82%A2%E3%83%9C%E3%82%BF%E3%83%B3%20-%20Qiita%20https%3A%2F%2Fqiita.com%2Fmod_poppo%2Fitems%2Fd80ff225b4cc93318ee8"
   >トゥート</a>
<a class="mastodon-share-button"
   target="_blank"
   rel="noopener noreferrer"
   href="web+mastodon://follow?uri=mod_poppo%40mstdn.jp"
   >@mod_poppo@mstdn.jpをフォローする</a>
<script>
if (!navigator.registerProtocolHandler) {
  document.body.classList.add("no-protocol-handlers");
}
</script>
```

見た目：

![スクリーンショット 0030-08-17 0.02.11.png](https://qiita-image-store.s3.amazonaws.com/0/185919/d6fb23ae-5e0e-be79-4383-33b3a0c75952.png)

デモ：[Mastodon向け簡易シェアボタン デモページ](https://miz-ar.info/mastodon-test.html)

# 関連リンク

- [@pacochi@pawoo.net 氏による web+mastodon: の解説](https://pawoo.net/@pacochi/40193187)
- [登録不要のマストドンのシェアボタンを作って更新した - Qiita](https://qiita.com/N_shi/items/8f3ff2d8cd0037bf7a46) （MastoshareのQiita記事）
- GitHub (tootsuite/mastodon) 内
    - Issue: [URL scheme for remote follow, share buttons · Issue #2291 · tootsuite/mastodon](https://github.com/tootsuite/mastodon/issues/2291)
    - プルリク：[Add protocol handler. Handle follow intents by Gargron · Pull Request #4511 · tootsuite/mastodon](https://github.com/tootsuite/mastodon/pull/4511)
    - 実装（渡されたURLの `share?text=` とか `follow?uri=` とかを解釈する部分） [app/controllers/intents_controller.rb](https://github.com/tootsuite/mastodon/blob/master/app/controllers/intents_controller.rb)
    - v1.6.0 のリリースノート：[Release v1.6.0 · tootsuite/mastodon](https://github.com/tootsuite/mastodon/releases/tag/v1.6.0)