(2022-11-25)
RustでMastodonやMisskeyのサーバーと通信することをとりあえずの目標に
(2022-11-25)
用語
ActivityPub (2022-11-25)
仕様
ActivityPub
w3c.github.io
ActivityPub
The ActivityPub protocol is a decentralized social networking protocol
based upon the [ActivityStreams] 2.0 data format.
It provides a client to server API for creating, updating and deleting
content, as well as a federated server to server API for delivering
notifications and content.
argrath.github.io
mastodonの仕様
ActivityPub - Mastodon documentation
A decentralized social networking protocol based upon the ActivityStreams 2.0 data format and JSON-LD.
docs.joinmastodon.org
WebFinger (2022-11-25)
RFC 7033: WebFinger
www.rfc-editor.org
WebFinger - Mastodon documentation
Translate `user@domain` mentions to actor profile URIs.
docs.joinmastodon.org
Activity Streams / Activity Vocabulary (2022-11-25)
Activity Streams 2.0
www.w3.org
Activity Vocabulary
www.w3.org
ActivityPubはActivityStreamのデータ形式を使用していてそのデータ型がActivity Vocabularyってことだと思う
json-ld (2022-11-25)
JSON-LD 1.1
JSONは、データのシリアル化と送受信に便利な形式です。この仕様では、リンクト・データをシリアル化するためのJSONベースの形式であるJSON-LD 1.1を定義しています。この構文は、既にJSONを用いている展開済みのシステムに容易に統合できるように設計されており、JSONからJSON-LDにスムーズにアップグレードするための道筋を示します。これは、ウェブ・ベースのプログラミング環境におけるリンクト・データの利用、相互運用可能なウェブ・サービスの構築、JSONベースのストレージ・エンジン内のリンクト・データの格納のための手段となることを主に意図しています。
www.asahi-net.or.jp
JSON-LD 1.1
JSON is a useful data serialization and messaging format.
This specification defines JSON-LD 1.1, a JSON-based format to serialize
Linked Data. The syntax is designed to easily integrate into deployed
systems that already use JSON, and provides a smooth upgrade path from
JSON to JSON-LD.
It is primarily intended to be a way to use Linked Data in Web-based
programming environments, to build interoperable Web services, and to
store Linked Data in JSON-based storage engines.
www.w3.org
最初JSON-LDってJSON Schemaと何が違うのと思ったけどそれは表面的なもの。
JSON SchemaはJSONのバリデーションをするがJSON-LDは要素にそれが何であるかの情報を与える。
JSON SchemaはJSONのバリデーションをするがJSON-LDは要素にそれが何であるかの情報を与える。
それと
json-ldで表されたデータの一種がacitivity streamってことでいいのかな?
W3C wikiによると「 What is the exact relation between JSON-LD and Activity Streams ? ("compatible" is not precise enough)」らしい。
application/ld+json
とapplication/activity+json
の違いがよくわからないjson-ldで表されたデータの一種がacitivity streamってことでいいのかな?
W3C wikiによると「 What is the exact relation between JSON-LD and Activity Streams ? ("compatible" is not precise enough)」らしい。
(2022-11-25)
参考文献
(2022-11-25)
Mastodonにアカウントとして認識されるActivityPubを実装してみる #Python - Qiita
Mastodonの検索エリアにURLを突っ込んだ際にアカウント化(?)させるにはどういう実装が必要なのか、気になって調べて実装してみた。結局ActivityPub対応WebFinger対応H…
qiita.com

とりあえずアカウントを認識させるところまで (2022-11-25)
use axum::{
extract::{Host, Path, Query},
routing::get,
Json, Router,
};
use serde::{Deserialize, Serialize};
use tracing::info;
static HOST: &str = "https://example.com";
static HOSTNAME: &str = "example.com";
#[tokio::main]
async fn main() {
tracing_subscriber::fmt::init();
let app = Router::new()
.route("/", get(|| async { "Hello, World!" }))
.route("/users/:id", get(user_get_handler))
.route("/.well-known/webfinger", get(webfinger_get_handler));
axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
.serve(app.into_make_service())
.await
.unwrap();
}
#[derive(Serialize)]
struct PersonActivity {
#[serde(rename = "@context")]
context: String,
#[serde(rename = "type")]
_type: String,
id: String,
name: String,
#[serde(rename = "preferredUsername")]
preferred_username: String,
summary: String,
inbox: String,
outbox: String,
url: String,
}
async fn user_get_handler(Path(user_id): Path<String>, host: Host) -> Json<PersonActivity> {
info!("user_get: query: {:?}", user_id);
info!("from: {:?}", host);
Json(PersonActivity {
context: "https://www.w3.org/ns/activitystreams".to_string(),
_type: "Person".to_string(),
id: format!("{}/users/{}", HOST, user_id),
name: user_id.clone(),
preferred_username: user_id.clone(),
summary: "".to_string(),
inbox: format!("{}/users/{}/inbox", HOST, user_id),
outbox: format!("{}/users/{}/outbox", HOST, user_id),
url: format!("{}/users/{}", HOST, user_id),
})
}
#[derive(Deserialize, Debug)]
struct WebFingerQuery {
resource: String,
}
#[derive(Serialize)]
struct WebFingerResponse {
subject: String,
aliases: Vec<String>,
links: Vec<WebFingerResponseLink>,
}
#[derive(Serialize)]
struct WebFingerResponseLink {
#[serde(skip_serializing_if = "Option::is_none")]
rel: Option<String>,
#[serde(rename = "type")]
_type: String,
#[serde(skip_serializing_if = "Option::is_none")]
href: Option<String>,
}
async fn webfinger_get_handler(query: Query<WebFingerQuery>) -> Json<WebFingerResponse> {
info!("webfinger_get query: {:?}", query);
let query_cap = regex::Regex::new(r"^acct:([^@]+)@(.+)$")
.unwrap()
.captures(&query.resource)
.unwrap();
let user_name = query_cap.get(1).unwrap().as_str();
let response = WebFingerResponse {
subject: format!("acct:{}@{}", user_name, HOSTNAME),
aliases: vec![format!("{}/user/{}", HOST, user_name)],
links: vec![WebFingerResponseLink {
rel: Some("self".to_string()),
_type: "application/activity+json".to_string(),
href: Some(format!("{HOST}/users/{}", user_name)),
}],
};
Json(response)
}
色々つっこみ所が多いがまあとりあえず
ハマったところ (2022-11-25)
webfingerとは?
これは
このときresouceには
WebFinger仕様にはacctスキーマについて
username@example.com
という一意のindetityについて関連するURLを取りにいくもののようでmastodonやmisskeyでは/.well-known/webfinger?resource=
に取りにくる。このときresouceには
acct:username@example.com
というリクエストが来る。WebFinger仕様にはacctスキーマについて
WebFinger requests include a "resource" parameter (see Section 4.1)
specifying the query target (URI) for which the client requests
information. WebFinger is neutral regarding the scheme of such a
URI: it could be an "acct" URI [18], an "http" or "https" URI, a
"mailto" URI [19], or some other scheme.
とある。
webfingerで決まっているわけではないがこの形式の一意のIDを扱うときはacctスキームを付けるのが普通みたい?
webfingerで決まっているわけではないがこの形式の一意のIDを扱うときはacctスキームを付けるのが普通みたい?
エンドポイントのURLは?
mastodonだとURL(example.com/users/xxx)をつっこんでも取りにきてくれなかった。
misskeyだとこれを入れるとこのURLにactivitystreamを取りにきた。そりゃそうか。
misskeyだとこれを入れるとこのURLにactivitystreamを取りにきた。そりゃそうか。
(2022-11-25)
というかよく考えたらjson-ldにちゃんと対応させるとめちゃくちゃ大変では
serde用のパーサはあるけど静的に型を付けるのとすごく相性が悪いような・・・
このクレートだとattribute macroでいろいろ頑張ってくれてるみたいだけどそれでもキツそう
serde用のパーサはあるけど静的に型を付けるのとすごく相性が悪いような・・・
このクレートだとattribute macroでいろいろ頑張ってくれてるみたいだけどそれでもキツそう
(2022-11-25)
と思ったけどどうやらjson-ldに対応している必要は一応ないみたい
ただスキーマを詠み込めるといろいろいいことがある感じかな
ただスキーマを詠み込めるといろいろいいことがある感じかな
(2022-11-25)
あと思ったのがフロントを分離しづらいということ
フロントはNext.jsでVercelとかにデプロイして別にバックエンドサーバーを作るつもりだったけど
フロントが
まあWorkersとかでリダイレクトさせればいいのかもしれないけどフロントにそれを意識させたくないのでstaticなファイルもaxumから配信するしかない
フロントはNext.jsでVercelとかにデプロイして別にバックエンドサーバーを作るつもりだったけど
フロントが
example.com
、APIサーバーがapi.example.com
にあったとしてインスタンスとして認識されるのはexample.com
だからそっちにFederationの情報を取りにくるまあWorkersとかでリダイレクトさせればいいのかもしれないけどフロントにそれを意識させたくないのでstaticなファイルもaxumから配信するしかない
(2023-02-14)
そういえば鍵垢ってどうやって実現してるんだろうか
ActivityPub
The ActivityPub protocol is a decentralized social networking protocol
based upon the [ActivityStreams] 2.0 data format.
It provides a client to server API for creating, updating and deleting
content, as well as a federated server to server API for delivering
notifications and content.
argrath.github.io
この内容からすると認証なしでリクエストが来た場合にはパブリックな投稿のみを返すという仕様だと思われる
そもそも鍵垢というのはどういうことかというとフォローを自由にできないというだけであって投稿の公開範囲には関係がないはずだ