ActivityPubサーバーに引用を実装

自作実装のActivityPubサーバーに「引用」を実装した。
引用ってナニ?
気になる投稿を見かけて、その投稿についてコメントをつけたい、なんて思った時にその投稿を自分の投稿に埋めこむ、文字通り「引用」する機能。
XなどのSNSではすでに利用されていて、フェディバースでもMisskeyやFedibird、kmyblueなどのサーバーでは実装されている。
なんで今さら?
つい先日、フェディバースでもっともポピュラーなMastodonというサーバーがこの「引用」を実装して運用を始めたから。
「引用」はXなんかのSNSでよく見られる「どれどれ、おれさまがモノ申してやろう」によく使われている。
投稿主の意図とは関係なく「晒しあげ」に使われることが多い、という問題を抱えているんで、Mastodonは引用の導入に消極的だという話があった。
てこともあってのことだと思うけど、引用の導入については、引用する該当の投稿が引用を許可しているか、偽装されていないかなど、ハードルを設けている。
わたしの場合、「おれさまがモノ申す」するような、みっともないマネはしたくない、でも、自分の過去投稿を引用したいことは「言い足したい」などでけっこうある。
ということで、ウチに実装する「引用」は、自分の投稿を自分で引用する「自己完結型」引用とする。
という無駄に長い前置き…老人の特権で勘弁してください。
で、引用の実装。
https://codeberg.org/fediverse/fep/src/branch/main/fep/044f/fep-044f.md
↑Mastodonの引用について
これがすべて。
・引用の許可
投稿のJSONに「引用を許可します」を明記する
"interactionPolicy":{"canQuote":{"automaticApproval":["https://www.w3.org/ns/activitystreams#Public"]}}
「interactionPolicy」というそのまんまの要素に、「canQuote」というそのまんまのキー。この値に「public」が指定されていると誰でも引用できる投稿となる。
・投稿を引用する
引用が許可された投稿を引用する
"quote": "https://tokoroten.doncha.net/t2aki/items/05829-20250921",
"quoteUrl": "https://tokoroten.doncha.net/t2aki/items/05829-20250921",
"quoteUri": "https://tokoroten.doncha.net/t2aki/items/05829-20250921",
"_misskey_quote": "https://tokoroten.doncha.net/t2aki/items/05829-20250921",
引用する投稿をJSONに記載する。Mastodonは「quote」だけど、すでに実装済みのサーバーとの互換のために「_misskey_quote」なども記載しておく。
この投稿には引用がついていて、引用する投稿のURLを書いておくね、ということになる、かな。
・引用のチェック
引用を含んだ投稿を受け取ったサーバーは、その引用が「正しいのか/表示していいのか」を確認する必要がある。
引用を含んだ投稿には、引用する投稿のURLのほかに「quoteAuthorization」のURLを記載する。
"quoteAuthorization": "https://tokoroten.doncha.net/t2aki/quote_auth/05833",
このURLにGETでリクエストして、返ってくるJSONで引用の整合性を確認する。
以下が「quoteAuthorization」が返すJSON
{
"@context": [
"https://www.w3.org/ns/activitystreams",
{
"gts": "https://gotosocial.org/ns#",
"quoteAuthorization": {
"@id": "https://w3id.org/fep/044f#quoteAuthorization",
"@type": "@id"
},
"interactingObject": {
"@id": "gts:interactingObject"
},
"interactionTarget": {
"@id": "gts:interactionTarget"
}
}
],
"id": "https://tokoroten.doncha.net/t2aki/quote_auth/05833",
"type": "QuoteAuthorization",
"attributedTo": "https://tokoroten.doncha.net/t2aki",
"interactingObject": "https://tokoroten.doncha.net/t2aki/items/05833-20250921",
"interactionTarget": "https://tokoroten.doncha.net/t2aki/items/05829-20250921"
}
以下すべての一致が確認できたら引用として表示される。
・idと引用投稿の「quoteAuthorization」
・attributedToと引用される投稿のattributedTo
・interactionObjectと引用投稿のid
・interactionTargetと引用される投稿のid
以上で最低限、自己完結型引用を投稿できる

↑mastodon.socialで引用投稿を表示
上記はいろいろ省略してる。
contextに記載するものもそうだけど、自己完結じゃない場合、ひとさまの投稿を引用する時にはリクエストのキャッチボールが生じるので対応が必要となる。
その投稿を引用したい!
・「"type": "QuoteRequest"」のActivityを引用したい投稿の主にPOSTでリクエストする。
・リクエストを受けたら承認(Accept)/拒否(Reject)のリクエストを返す。
返事を見てから引用をする/しない。
とはいえ、自己完結型は承認もなにもないので、このへんはばっさりスルー。
引用したい側は、引用元に可否を問い合わせるのは「MUST」
引用される側は、返事する/しないはおまかせ
ということだし。
このブログはもともとコード掲載することを考えてなくて、めっちゃ見にくいんで、そのうちホームページの方に改めて掲載します。
「おひとり様ActivityPubサーバーの自作実装::On Golden Pond」
今日時点、引用にしても絵文字にしても、ActivityPubの仕様にはない(?)ので、サーバーごとで対応にバラつきがあって、現物合わせの手探り。
判じ物、当たるも八卦当たらぬも八卦(死語)の世界だなあ。
[09/22 09:50:38]追記
あれ?自己完結するなら、interactionPolicyは不要な気がする。
あとで検証してみよう
[09/23 23:09:35]追記
intractionPolicyは不要だった。
これは「引用しようとするひと向け」のもので、自己完結するなら不要。
intractionPolicyは本家Mastodonの引用制御
・誰でも引用できる
・followerまでが引用できる
・引用できるのは自分だけ
この選択のためにある。
引用を含んだ投稿を表示させる時に、引用されている投稿の引用ポリシーを確認にくるのでは、と疑ったんだけど、アクセスログを見てもそんな形跡もなかった。
ということはquoteAuthorizationの設定だけ約束どおり作っておけば、引用を含んだ投稿を意図通り表示してくれる。

