DB不要! サイトとSNSアカウントがあればできます。

🔗

私が実装したものです。GitHub Pagesで作りました。このサイトにコメントするには、以下の手順でできます。

  1. 以下サービスのどれかでアカウントを作る
  2. コメントしたいサイトのURLhttps://ytyaru.github.io/を入力してツイートやトゥートする
  3. サイト下部のコメント欄にそのツイートやトゥートが表示される

20220527154355_020_resize.png

コメント欄にあるytyaru_webmentionというユーザをクリックすると、そのリンク先はmstdn.jp内の@ytyaru_webmentionユーザページです。なにせそのトゥートをブログに埋め込んでいるわけですから。もしツイッターからのコメントなら、ツイッターのユーザページになるはずです。

よろしければ皆さんも試してみてください。表示には時間がかかるかもしれません。

ytyaruのプロフィールのページには、この記事を投稿した時点でコメントが3件あります。これはすべて私がテストしたものです。mstdn.jpでアカウントを2つとり、1つをサイト管理者用、もうひとつをサイトにコメントをつける用としてテストしました。

mstdn.jpアカウント 用途
@ytyaru サイトのHTMLに管理者用アカウントとしてセットする``
@ytyaru_webmention サイトURLを入れてトゥートする(サイトのコメント欄に表示される)

やる価値 🔗

これを実装するのは大変です。けれど大いにやる価値があります。今まではツイートボタンとコメント欄が別々でしたが、これからはwebmention.ioで統合できます。すると、次のような嬉しいことが起こるでしょう。

  • UIがシンプルになってスッキリします
  • SNSアカウントが必要なので、スパムが来にくくなるでしょう
  • JSONで取得できるので、コメント欄を好きなように作り込めます
  • 自前でDBやサーバを用意する必要がありません

無料のHTTPSホストサーバは大抵DBやサーバサイド言語を使うことができません。その条件でコメント欄を使うには、Disqusという外部サービスを使う手がありました。

しかし一企業に依存するのは危険です。これまでいくつものサービスが生まれては消え、そのたびにユーザはデータ消失という大事件に巻き込まれてきたのです。それに嫌気が差したかどうかは知りませんが、反旗を翻した存在がいました。Indie Webです。彼らは企業の支配から逃れ、独立して、コメントなどの情報をユーザが自分で管理できる仕組みを作りました。それがwebmention.ioです。私はそう解釈しました。

さあ、あなたも今日からIndie Webで、コメントを自由に管理しましょう!

必要なもの 🔗

  • 自分のサイト
  • 自分のSNSアカウント(TwitterかMastodon)

システム概要 🔗

  • webmention.ioはリクエストされた記事を解析してDBを作る。それを返すAPIを提供する
  • brid.gyはツイッターやマストドンなどいくつかのサービスで作られた記事から自動的にwebmention.io用のHTMLを作成し、定期的にwebmention.ioへDBを作るようリクエストする
  • 私たちエンドユーザはwebmention.ioのAPIを使って、返されたJSONからコメント情報を取得してHTMLを作り表示する

手順 🔗

サイトとSNSアカウントの作成は終わっているものとします。

  1. webmention.ioにサイトを登録する
  2. brid.gyにツイッターやマストドンのアカウントでログインする
  3. サイトにWebmention用HTMLコードを埋め込む
  4. サイトにコメント欄表示用JavaScriptコードを実装する
  5. ツイートやトゥートする
  6. 待つ
  7. サイトにツイートやトゥートが表示される

1. webmention.ioにサイトを登録する 🔗

  • webmention.ioに自分のサイトのURLをドメイン名まで入力する:https://example.com
  • ツイッターのアカウントに紐付ける(ユーザ名とパスワードを入力する)

2. brid.gyにツイッターやマストドンのアカウントでログインする 🔗

  • brid.gyにアクセスする
  • ツイッターやマストドンのボタンがあるのでクリックする
  • 自分のアカウントでログインする
  • 自分のサイトURLをドメイン名まで入れる
  • Doneボタンを押す
  • 反応が表示される

私は次のサービスを連携させました。

なので、上記3サービスからの反応を取得できます。

3. サイトにWebmention用HTMLコードを埋め込む 🔗

3-1. サイトのドメインを指定する 🔗

<link rel="webmention" href="https://webmention.io/あなたのサイトのドメイン名/webmention" />
<link rel="pingback" href="https://webmention.io/あなたのサイトのドメイン名/xmlrpc" />

たとえば私のサイトのURLはhttps://ytyaru.github.io/なのでドメイン名はytyaru.github.ioです。よって次のようになります。

<link rel="webmention" href="https://webmention.io/ytyaru.github.io/webmention" />
<link rel="pingback" href="https://webmention.io/ytyaru.github.io/xmlrpc" />

3-2. SNSアカウントを指定する 🔗

webmention.iobrid.gyで連携させた、自分のSNSアカウントのプロフィールURLを指定します。

<link rel="me" href="https://twitter.com/あなたのツイッターID">

私の場合は次のようになりました。

<link rel="me" href="https://twitter.com/ytyaru1">
<link rel="me" href="https://mstdn.jp/@ytyaru">
<link rel="me" href="https://pawoo.net/@ytyaru_pawoo">

rel="me"という属性により、自分自身であることを表しています。この属性は<a>タグでも付与できます。たとえば次のようにも書けます。

<a rel="me" href="https://twitter.com/ytyaru1" title="Twitter"><img src="./twitter.png" width="64" height="64"></a>

表示するか、しないかで使い分けるとよいでしょう。

3-3. SNSプロフィールのURL欄に自分のサイトURLを指定する 🔗

  1. ツイッターなりマストドンなりでログインするログインする
  2. プロフィール設定する
  3. URL入力欄に自分のサイトのURLを入力する

URL欄がなければ、自由欄に入力する。

4. サイトにコメント欄表示用JavaScriptコードを実装する 🔗

webmention APIを実行します。するとツイートやトゥートの情報がJSON形式で返ってきます。それを使ってJavaScriptのDOM操作でHTMLを作成し、コメント欄として表示させます。

4-1. 数を取得する 🔗

ツイートやらトゥートやらをされた数を取得します。

const target = location.href // あなたのサイトのドメイン名やその下にあるページなど
const res = await fetch(`https://webmention.io/api/count?target=${this.target}`)
const json = await res.json()

すると以下のようなJSONが返ってきます。

{
"count": 6,
"type": {
    "bookmark": 1,
    "mention": 2,
    "rsvp-maybe": 1,
    "rsvp-no": 1,
    "rsvp-yes": 1
}

countプロパティが目的の値です。これを表示しましょう。

HTMLに以下のような要素を作ります。

<span id="web-mention-count"></span>

JavaScriptでその要素に、先程のcount値をぶちこみます。

document.getElementById('web-mention-count').textContent = `${json['count']} mensions`

これでツイートやトゥートなどの反応数を表示することができます。

4-2. コメントを取得する 🔗

以下のようにWebmention APIを実行します。

const res = await fetch(`https://webmention.io/api/mentions.jf2?target=${this.target}&sort-by=published&sort-dir=down&per-page=${this.per}&page=0`)
const json = await res.json()

すると、次のようなJSONが返ってきます。

[
{
  "type": "entry",
  "author": {
    "type": "card",
    "name": "Tantek Çelik",
    "url": "http://tantek.com/",
    "photo": "http://tantek.com/logo.jpg"
  },
  "url": "http://tantek.com/2013/112/t2/milestone-show-indieweb-comments-h-entry-pingback",
  "published": "2013-04-22T15:03:00-07:00",
  "wm-received": "2013-04-25T17:09:33-07:00",
  "wm-id": 900,
  "content": {
    "text": "Another milestone: @eschnou automatically shows #indieweb comments with h-entry sent via pingback http://eschnou.com/entry/testing-indieweb-federation-with-waterpigscouk-aaronpareckicom-and--62-24908.html",
    "html": "Another milestone: <a href=\"https:\/\/twitter.com\/eschnou\">@eschnou<\/a> automatically shows #indieweb comments with h-entry sent via pingback <a href=\"http:\/\/eschnou.com\/entry\/testing-indieweb-federation-with-waterpigscouk-aaronpareckicom-and--62-24908.html\">http:\/\/eschnou.com\/entry\/testing-indieweb-federation-with-waterpigscouk-aaronpareckicom-and--62-24908.html<\/a>"
  },
  "mention-of": "https://indieweb.org/",
  "wm-property": "mention-of",
  "wm-private": false
},
]

これはコメント一件分のデータです。プロパティ名から大体わかると思います。たとえばcontent.htmlがコメントの内容です。author.nameがコメントした人の名前です。

とりあえず以下のようなHTMLにしましょう。アバター画像、ユーザ名、ユーザURLリンク、公開日時、コメント内容を表示します。

<div class="mention">
  <div class="mention-meta">
    <a href="${author.url}">
      <img src="${author.photo}" alt="${author.name}" width="32" height="32">
      <span>${author.name}<span>
    </a> <span>${published}</span>
    <div>${content}</div>
  </div>
</div>

細かいことは省きます。ようするに、webmention APIから返ってきたJSONを使って、自力で好きなようにコメント欄を作るということです。大変でしたが楽しかったです。皆さんはもっとカッコいいコメント欄を作ってもいいのですよ?

完成したらサイトをデプロイ(アップロード)します。

5. ツイートやトゥートする 🔗

早速、自分のサイトにツイートやトゥートしてみましょう。けれどちょっと待ってください。サイトにrel="me"で指定したアカウントでツイートしても表示されません。コメント欄に表示されるためには以下の条件を満たす必要があります。

  • brid.gyで連携したサービスのアカウントであること
  • rel="me"で指定したもの以外のアカウントであること
  • ツイートの内容に対象ブログのURLが含まれていること

というわけで、テスト用に別のアカウントを取得することをおすすめします。Mastodonが取りやすいでしょう。アカウント取得後、ブログのURLを含めてトゥートします。

6. 待つ 🔗

brid.gyがクロールするまで待ちます。待てなければbrid.gyのサイトでクロールをリクエストしましょう。

7. サイトにツイートやトゥートが表示される 🔗

おめでとうございます。これであなたのブログにツイートされたらコメント欄として表示されるようになりました!

さらに詳しく 🔗

これによると、返信内容は独自のHTML形式によって表現できるらしいです。それをGitHub PagesなどのHTTPSホストサービスにアップロードして、webmentionにリクエストすると、コメントのデータとして登録されるようです。詳しくは以下を参照してください。

所感 🔗

いかがでしたか? 大変だったでしょう? 私はめちゃくちゃ苦労しました。でも気になっていた技術だったので、実装できてよかったです。コメント欄を自分で作るのも大変でしたが楽しかった。いずれ、ちゃんとしたコードを書きたいものです。