Ekasiliconのゴミ捨て場

ゴミがあります。そこに。

さっくりわかるActivityPub

初めましての方は初めまして。Ekasiliconと申します。さて私は去る2024年5月11日に開催されたUNTIL.LT #0x04に参加させていただきました。

そこにおいて「さっくりわかるActivityPub」というタイトルで10分間のLTをしました。この記事ではどのような話をしたのかをブログの記事という形にして記録していこうかと思います。

タイトル

さっくりわかるActivityPub

あーすというところに所属しております。Ekasiliconと申します。さて今回私は「さっくりわかるActivityPub」というタイトルでお話をさせていただこうかと思います。

ちょっと前から話題になっているかもしれないMisskeyやMastodon、いわゆる分散型SNS(この呼び方はそこまで好きじゃない)と呼ばれているものに関係する話で、普通に面白いポイントがある技術だと思っているので、皆さんに"さっくりと"理解していただいた上で、興味を持っていただければ嬉しいなと思います。

話すこと・話さないこと

前回試験的に行ってみて割と好評だった、話すこと・話さないことについて簡単に説明していこうと思います。まず以下のことについて話します。

  • Fediverseの概念
  • ActivityPubとは
  • 簡単な歴史(RSS等)
  • 嬉しいところ

反対に以下のことについては説明しません。

  • HTTPそのもの
  • 込み入ったActivityPubの話
  • JSON
  • 詳しい歴史
  • つらいところ(布教したいので)

こういった内容については、よしなに憶測で補ったり調べていただいたりしていただければと思います。

Bluesky、一般公開

さて先日…といっても2月の話ですが、Blueskyが招待制ベータから誰でも登録できる公開の正式版となりました。ついでにロゴも青空から蝶になりました。蝶のように長生きしてくれれば嬉しいですね。

このBlueskyというものの売り文句の1つに「分散型」というのもあって、MisskeyやMastodonを思い浮かべた方もいるかもしれません。しかしながらこれは「AT Protocol」という新規設計されたプロトコルを使用しており、MisskeyやMastodonといったものが使用している「ActivityPub」とは異なるプロトコルです。今回はBlueskyとは関係ない、MisskeyやMastodonなどと関連するプロトコルについて話していきたいと思います。

MastodonとかMisskeyとか

先ほどから話しているMisskeyやらMastodonやらとはなんぞや、という話ですが、これはSNSのソフトウェア自身を指す言葉です。よく「Misskey始めました!」と言ってアットマーク以降の文字列を貼っている人がいますが、多くの場合それは開発者やそれに近しい人が運用しているサーバーのことを指すことが多いです。例えばMastodonであればMastodon.social、MisskeyであればMisskey.io、といった感じです。当然ながら全然別のサーバーも存在しており、つくばねすきー(mi.tsukuba.dev)においてはMisskeyというソフトウェアが動いていますが、Misskey.ioとは異なるものとなっています。

もちろんお持ちのサーバーへインストールすることも可能です。これらは自由ソフトウェアであって、勝手にソースを見た人が改善されていたりフォークされたりしています。

「連合」出来る

他にも先ほどから出ているワードとして「Fediverse」というものがありますが、これはどういうものでしょうか。前のスライドで説明させていただいたMastodonやMisskey等では、これらをインストールしているサーバー同士でコミュニケーションをとることが可能となっております。これを一般に「連合(Federation)」と呼んでいます。

情報同士が送られ合うといういわば「宇宙」のようなもののため、FederationとUniverseをくっつけて「Fediverse」と言っているわけです。さて、このFediverseはどうやって実現しているのでしょうか?

ActivityPub

それが先ほどから出ている「ActivityPub」というものです。これはW3Cから出ているHTTPの拡張、ということになっています。あんまりHTTPしているという感じはしないんですけどね。

MastodonやMisskeyの各サーバーには「INBOX」と「OUTBOX」があり、それぞれのサーバーが対応するものに応じて他のサーバーのこれらをGETやPOSTなどで叩く、という感じです。なんてナウでヤングなRESTワールドなんでしょう。

JSON-LDを使用

もちろんGETとPOSTだけで全てを賄っている、というわけではなく、送り付けあっているのはJSON-LDです。ただのJSONと何が違うかという話ですが、大まかに言えば「JSONのプロパティ名やデータ型などをきちんと定義した(ようなもの)」、という感じでしょうか。ちなみにRDFなどもこれによって表現が出来ます。

ActivityPubの世界ではActivity Streams 2.0で語彙を定義しています。一例を出すと、typeには「Note」、「Like」、「Follow」などがあります。SNS感がありますね。

アクター(各ユーザー)への変換

アクター(各ユーザー)への変換

もちろん、JSON-LDを送り付けあうだけではFediverseは成立しません。色々な面白い処理を行っています。ここでは一例としてアクター、一般的にはSNSを使っている各ユーザーへの変換を見ていきましょう。

ActivityPub上でアクターは「@ユーザー名@ドメイン」というメールアドレスのような形式で表記されます。例えばUNTIL.のアカウントであれば「@[email protected]」という感じです。ここで面白いのは、人間が見るべきものと機会が見るべきものが異なることがあり得る、異なるようにすることが出来るという点です。例としてはVivaldi Socialã‚„Instrgramが始めたThreadsが挙げられます。このようなものを実現するために、Host MetadataというものとWebFingerというものの合わせ技で解決しています。

まず「@ユーザー名@ドメイン」という形が与えられた場合、初めに[ドメイン]/.well-known/host-metaを見に行きます。ここにはWebfingerをどこに投げればいいのかが示されています。

その次に得られたWebfingerの投げ先が示された場合、その先を見に行きます。だいたい[ドメイン]/.well-known/webfinger?resource=“ユーザー名@ドメイン”みたいな感じです。ここには通信を行うべきアドレスと、人間が見るべきプロフィールページのURLが書かれていたりします。こうして受け取ったものをよしなにユーザーへ渡せばよいわけです。

一例(@vivaldi@vivaldi.netの場合)

$ curl social.vivaldi.net/.well-known/host-meta -L
<?xml version="1.0" encoding="UTF-8"?>
<XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
  <Link rel="lrdd" template="https://social.vivaldi.net/.well-known/webfinger?resource={uri}"/>
</XRD>

$ curl https://social.vivaldi.net/.well-known/webfinger?resource="[email protected]"
{"subject":"acct:[email protected]","aliases":["https://social.vivaldi.net/@Vivaldi","https://social.vivaldi.net/users/Vivaldi"],"links":[{"rel":"http://webfinger.net/rel/profile-page","type":"text/html","href":"https://social.vivaldi.net/@Vivaldi"},{"rel":"self","type":"application/activity+json","href":"https://social.vivaldi.net/users/Vivaldi"},{"rel":"http://ostatus.org/schema/1.0/subscribe","template":"https://social.vivaldi.net/authorize_interaction?uri={uri}"},{"rel":"http://webfinger.net/rel/avatar","type":"image/png","href":"https://social-cdn.vivaldi.net/system/accounts/avatars/109/338/455/962/321/184/original/882e31b8fd08cf9d.png"}]}

RSS

どうしてこのようなものが出来たのでしょうか、歴史を探るためにRSSの仕組みを眺めましょう。大まかに言えばRSSは以下の仕組みで動いています。

  1. ウェブサイト上で記事が追加・更新される
  2. 更新した旨をRSSファイルに記述する
  3. ユーザーはそのRSSファイルを定期的に取得し、前回取得した時の差分や時間を見て更新を把握する
  4. ユーザーはRSSファイルや更新されたWebサイトを見に行く

細かいところでは違うところもあるのですが、大まかに言えばこんな感じです。さて、ここにおいては大きく以下の問題があります。

  • リアルタイムに情報を得られない(ユーザーがRSSファイルを取得するまで更新された旨を知るすべがない)
  • 特定の記事に対してフィードバックや反応を送ることが出来ない(mailto:がスパムによって事実上使えなくなった)

これらをどうにかして解決しようと、先人たちは様々な発明を行ってきました。例えば、RSSからAtomにしてみたり、WebSub (PubSubHubbub)を作ってみたり、Salmon Protocolを提唱してみたり、Webfingerを作ってみたり…などなどです。このような技術をまとめて作られたのがOStatusです。これに対応したソフトウェアとしてGNU Socialが良く知られています。

ただOStatusが複雑になりすぎたということで、Pump.ioというプロジェクトがActivityPubの原型を提唱し、現在ではW3Cの勧告となっている、というのが大まかな流れです。ActivityPubはとてもシンプルということになっていますね。

対応しているソフトウェア

このような謎のプロトコル、ActivityPubというものに対応しているソフトウェアはそんなに無いのであろう、と思ってしまうかもしれませんが、実はそんなことはありません。例えば以下のようなソフトウェアが対応しています。

全世界のウェブサイトの半分くらいを占めているWordPressも(プラグインを入れれば)対応しているということですので、ActivityPubの輪は確実に広まっているといえるのではないでしょうか。SNS向けのものですので、受け取れる情報量にはどうしても差が出来てしまいますが、そこもまた面白いポイントでしょう。

嬉しいところ

というわけで最後に嬉しいところをまとめておこうかと思います。

  • 異なるソフトウェアとさえ通信出来る! - もちろん制限されるところもある。しかし1つのアカウントでコミュニケーションが取れる。
  • 大富豪にお金を払わなくとも本人証明が出来る - 自分が所有しているドメインでサーバーを立てればよい。Blueskyのドメインをハンドルネームのようにするのとは異なります。
  • 変な技術なので面白い - HTTP(とその他もろもろ)でこれが実現できるの??という驚きがあります。基本となっているのはお馴染みのWeb技術です。

最後に

というわけでActivityPubをさっくり説明しました。何となく理解してくれれば嬉しいです。ありがとうございました。