Skip to content

Instantly share code, notes, and snippets.

@tateisu
Created December 19, 2018 03:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tateisu/f3a3fe6bfa854ff02b61cdd76abc63e5 to your computer and use it in GitHub Desktop.
Save tateisu/f3a3fe6bfa854ff02b61cdd76abc63e5 to your computer and use it in GitHub Desktop.
ActivityPubでタイムラインを見るまで
#################################################
GET /.well-known/host-meta
that defined in RFC6415 'Web Host Metadata'
応答例
<?xml version="1.0" encoding="UTF-8"?>
<XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
<Link rel="lrdd" type="application/xrd+xml" template="https://mastodon.juggler.jp/.well-known/webfinger?resource={uri}"/>
</XRD>
このtemplate の {uri} 部分に
acct:tateisu@mastodon.juggler.jp や
https://mastodon.juggler.jp/@tateisu を入れる
########################################
WebFinger
https://mastodon.juggler.jp/.well-known/webfinger?resource=acct:tateisu@mastodon.juggler.jp
https://mastodon.juggler.jp/.well-known/webfinger?resource=https://mastodon.juggler.jp/@tateisu
応答例
{
"subject":"acct:tateisu@mastodon.juggler.jp",
"aliases":[
"https://mastodon.juggler.jp/@tateisu",
"https://mastodon.juggler.jp/users/tateisu"
],
"links":[
{
"rel":"http://webfinger.net/rel/profile-page",
"type":"text/html",
"href":"https://mastodon.juggler.jp/@tateisu"
},
{
"rel":"http://schemas.google.com/g/2010#updates-from",
"type":"application/atom+xml",
"href":"https://mastodon.juggler.jp/users/tateisu.atom"
},
{
"rel":"self",
"type":"application/activity+json",
"href":"https://mastodon.juggler.jp/users/tateisu"
},
{
"rel":"salmon",
"href":"https://mastodon.juggler.jp/api/salmon/1"
},
{
"rel":"magic-public-key",
"href":"data:application/magic-public-key,RSA.pDbofJn1MWKrwNwVJX-sWVkT0ucQlmsWeE1-XnOCm1GVQF3PDPP6Msx-eoMpNgtDjkcdOo1PD_ZzQEvZvvZ8xUP2NqfPJLrAzax0XuSAJC8Tta59iUIlUsDWhdehTnjCTS9r-7enTd_m_BRsu6MFk2ko7DazNk6bip9RWS5yPTSylITvgK38B8QpwSbkdNvX67OHT3yr75ByE9UJNDQ5Q_3SKnWTOt0l2Ov1vzs_Fcc1V-7kzDjzF931HqKKQA_3AcSBsZYi4AuVjBQWx80RX95c3iaP7lOkaGXWRfG7Fz7OnbB7pFas1rxbvfgUiTJpiLhbwQAqcQdySU5v6ZOt3Q==.AQAB"
},
{
"rel":"http://ostatus.org/schema/1.0/subscribe",
"template":"https://mastodon.juggler.jp/authorize_interaction?uri={uri}"
}
]
}
"type":"application/activity+json" に書かれたhrefのurlで
ActivityPubのオブジェクトを取得できる。
########################################
ActivityPubのオブジェクトの取得(AP3.2)
Accept: application/activity+json
Accept: application/ld+json; profile="https://www.w3.org/ns/activitystreams"
(前者を推奨)のヘッダをつけてGETする。
###########################################
* ActivityPub オブジェクトの取得
Accept: application/activity+json
GET https://mastodon.juggler.jp/users/tateisu
{
"@context":[
"https://www.w3.org/ns/activitystreams",
"https://w3id.org/security/v1",
{
"manuallyApprovesFollowers":"as:manuallyApprovesFollowers",
"sensitive":"as:sensitive",
"movedTo":{
"@id":"as:movedTo",
"@type":"@id"
},
"Hashtag":"as:Hashtag",
"ostatus":"http://ostatus.org#",
"atomUri":"ostatus:atomUri",
"inReplyToAtomUri":"ostatus:inReplyToAtomUri",
"conversation":"ostatus:conversation",
"toot":"http://joinmastodon.org/ns#",
"Emoji":"toot:Emoji",
"focalPoint":{
"@container":"@list",
"@id":"toot:focalPoint"
},
"featured":{
"@id":"toot:featured",
"@type":"@id"
},
"schema":"http://schema.org#",
"PropertyValue":"schema:PropertyValue",
"value":"schema:value"
}
],
"id":"https://mastodon.juggler.jp/users/tateisu",
"type":"Person",
"following":"https://mastodon.juggler.jp/users/tateisu/following",
"followers":"https://mastodon.juggler.jp/users/tateisu/followers",
"inbox":"https://mastodon.juggler.jp/users/tateisu/inbox",
"outbox":"https://mastodon.juggler.jp/users/tateisu/outbox",
"featured":"https://mastodon.juggler.jp/users/tateisu/collections/featured",
"preferredUsername":"tateisu",
"name":"tateisu​:force:​:r_9a:",
"summary":"\u003cp\u003eSubway Tooter 開発者\u003cbr /\u003emastodon.juggler.jp 管理者\u003c/p\u003e",
"url":"https://mastodon.juggler.jp/@tateisu",
"manuallyApprovesFollowers":false,
"publicKey":{
"id":"https://mastodon.juggler.jp/users/tateisu#main-key",
"owner":"https://mastodon.juggler.jp/users/tateisu",
"publicKeyPem":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApDbofJn1MWKrwNwVJX+s\nWVkT0ucQlmsWeE1+XnOCm1GVQF3PDPP6Msx+eoMpNgtDjkcdOo1PD/ZzQEvZvvZ8\nxUP2NqfPJLrAzax0XuSAJC8Tta59iUIlUsDWhdehTnjCTS9r+7enTd/m/BRsu6MF\nk2ko7DazNk6bip9RWS5yPTSylITvgK38B8QpwSbkdNvX67OHT3yr75ByE9UJNDQ5\nQ/3SKnWTOt0l2Ov1vzs/Fcc1V+7kzDjzF931HqKKQA/3AcSBsZYi4AuVjBQWx80R\nX95c3iaP7lOkaGXWRfG7Fz7OnbB7pFas1rxbvfgUiTJpiLhbwQAqcQdySU5v6ZOt\n3QIDAQAB\n-----END PUBLIC KEY-----\n"
},
"tag":[
{
"id":"https://mastodon.juggler.jp/emojis/7480",
"type":"Emoji",
"name":":force:",
"updated":"2017-11-11T23:44:53Z",
"icon":{
"type":"Image",
"mediaType":"image/png",
"url":"https://mastodon.juggler.jp/system/custom_emojis/images/000/007/480/original/force.png?1510443893"
}
},
{
"id":"https://mastodon.juggler.jp/emojis/7483",
"type":"Emoji",
"name":":r_9a:",
"updated":"2017-11-12T00:21:17Z",
"icon":{
"type":"Image",
"mediaType":"image/png",
"url":"https://mastodon.juggler.jp/system/custom_emojis/images/000/007/483/original/r-9a.png?1510446077"
}
}
],
"attachment":[
{
"type":"PropertyValue",
"name":"Subway Tooter",
"value":"\u003ca href=\"https://github.com/tateisu/SubwayTooter\" rel=\"me nofollow noopener\" target=\"_blank\"\u003e\u003cspan class=\"invisible\"\u003ehttps://\u003c/span\u003e\u003cspan class=\"ellipsis\"\u003egithub.com/tateisu/SubwayToote\u003c/span\u003e\u003cspan class=\"invisible\"\u003er\u003c/span\u003e\u003c/a\u003e"
},
{
"type":"PropertyValue",
"name":"Amazon干し芋",
"value":"\u003ca href=\"http://amzn.asia/axmNivM\" rel=\"me nofollow noopener\" target=\"_blank\"\u003e\u003cspan class=\"invisible\"\u003ehttp://\u003c/span\u003e\u003cspan class=\"\"\u003eamzn.asia/axmNivM\u003c/span\u003e\u003cspan class=\"invisible\"\u003e\u003c/span\u003e\u003c/a\u003e"
}
],
"endpoints":{
"sharedInbox":"https://mastodon.juggler.jp/inbox"
},
"icon":{
"type":"Image",
"mediaType":"image/jpeg",
"url":"https://mastodon.juggler.jp/system/accounts/avatars/000/000/001/original/84b02105771fa764.jpg?1536296030"
},
"image":{
"type":"Image",
"mediaType":"image/jpeg",
"url":"https://mastodon.juggler.jp/system/accounts/headers/000/000/001/original/8520fa5b1c76acbe.jpg?1536296030"
}
}
###########################################
* ActivityPub オブジェクトの解釈
** Object
*** id (AP3.1)
> "id":"https://mastodon.juggler.jp/users/tateisu",
idは短命なものについては明示的にJSONのnull値をとる。
それ以外はHTTPS URI のような、公に展開可能な URI で、その権限が発信元サーバに 帰属するものである。
クライアントからサーバに送る場合、idなしにoutboxに送られたオブジェクトはサーバ側でidが割り当てられる。
*** type (AP3.1)
> "type":"Person",
オブジェクトの型。
*** source (AP3.3)
ActivityPub は Object に source 属性を提供するように拡張する。
content属性で提供されるHTML文章のオリジナルテキストとその記述形式が含まれる。
(source属性はマストドンの投稿outboxには含まれてない)
Object may have:
*** attachment (AS)
*** attributedTo (AS)
*** audience (AS)
*** content (AS)
*** context (AS)
*** contentMap (AS)
*** name (AS)
*** nameMap (AS)
*** endTime (AS)
*** generator (AS)
*** icon (AS)
*** image (AS)
*** inReplyTo (AS)
*** location (AS)
*** preview (AS)
*** published (AS)
*** replies (AS)
*** startTime (AS)
*** summary (AS)
*** summaryMap (AS)
*** tag (AS)
*** updated (AS)
*** url (AS)
*** to (AS)
*** bto (AS)
*** cc (AS)
*** bcc (AS)
*** mediaType (AS)
*** duration (AS)
############################################################
** Actor (Person?) (AP4)
*** inbox (AP5.2)(MUST)
> "inbox":"https://mastodon.juggler.jp/users/tateisu/inbox",
[ActivityStreams] OrderedCollection への参照
actor が受け取った全てのメッセージ
ユーザの場合、認証がないと404になる
inbox は actor のプロファイルの inbox プロパティを使って発見される。
inbox は OrderedCollection でなければならない(MUST)。
inbox は actor が受信した全てのアクティビティを含む。
サーバは要求者の権限に応じてコンテンツをフィルタリングするべきである(SHOULD)。
一般的に、inbox の所有者は その inbox のコンテンツ全てにアクセスできる。
アクセス制御に依存して、その他のコンテンツの一部はパブリックで、
一方その他のコンテンツは非所有者のユーザーは認証を要求されるかもしれない; if they can access the inbox at all.
サーバは inbox に返されたアクティビティの重複解消を 実行しなければならない(MUST)。
Duplication can occur if an activity is addressed both to an actor's followers,
and a specific actor who also follows the recipient actor, and the server has failed
to de-duplicate the recipients list.
このような重複解消は、アクティビティの id を比較して、
既に読んだアクティビティを落とす形で行われなければならない(MUST)。
連合サーバ上の actor の inbox は HTTP POST リクエストを受け付ける;
その振る舞いは Delivery に記述されている。
非連合サーバは POST リクエストを受け取った場合は 405 Method Not Allowed を 返すべきである(SHOULD)。
*** outbox (AP5.1)(MUST)
> "outbox":"https://mastodon.juggler.jp/users/tateisu/outbox",
[ActivityStreams] OrderedCollection への参照
この actor によって作成された全てのメッセージから成る
outbox は actor のプロファイルの outbox プロパティを使って発見される。
outbox は OrderedCollectionでなければならない(MUST)。
The outbox stream contains activities the user has published,
subject to the ability of the requestor to retrieve the activity
(that is, the contents of the outbox are filtered by the permissions of the person reading it).
ユーザーが Authorization なしでリクエストを投稿した場合、 サーバは全てを Public 投稿として 応答しなければならない。
これは潜在的にそのユーザーによって発行された、全ての関連するオブジェクトとなるかもしれないが、
利用可能なアイテムの数は実装とデプロイされたサーバの自由裁量に任されている。
outbox は HTTP POST リクエストを受け付ける; その振る舞いは Client to Server Interactionsに記述されている。
*** following (AP5.4)(MUST)
>"following":"https://mastodon.juggler.jp/users/tateisu/following",
[ActivityStreams] コレクションへのリンク
この actor がフォローしている actor を示す
各 actor は following コレクションを持つべきである(SHOULD)。
これは side effect として追加された、 この actor がフォローした相手の一覧である。
following コレクションは OrderedCollection または Collection でなければならず(MUST)、
認証されたユーザーの権限や、認証がない場合は適切な形でフィルタリングしても 良い(MAY)。
*** followers (AP5.3)(MUST)
>"followers":"https://mastodon.juggler.jp/users/tateisu/followers",
[ActivityStreams] コレクションへのリンク;
この actor をフォローしている actor を示す
各 actor は followers コレクションを 持つべきである(SHOULD)。
これはこの actor に Follow アクティビティを送信したときに 副作用 として追加された送信者の一覧である。
これは誰かがある actor をフォローしている全てのユーザーの一覧を 見つける場所である。
followers コレクションは OrderedCollection または Collection でなければならず(MUST)、
認証されたユーザーの権限や、認証がない場合は適切な形でフィルタリングしても 良い(MAY)。
*** liked (AP5.5)(MAY)
[ActivityStreams] コレクションへのリンク
この actor が好んでいるオブジェクトを示す
各 actor は liked コレクションを持っても良い(MAY)。
これは side effect として追加された、 この actor の全ての Like のオブジェクトの一覧である。
liked コレクションは OrderedCollection または Collection でなければならず(MUST)、
認証されたユーザーの権限や、認証がない場合は適切な形でフィルタリングしても 良い(MAY)。
*** Likes? (AP5.7)(MAY)
各オブジェクトは likes コレクションを持ってもよい(MAY)。
このオブジェクトへのLikeアクティビティのリスト。
The likes コレクションは OrderedCollection または Collection でなければならず(MUST)、
認証されたユーザーの権限や、認証がない場合は適切な形でフィルタリングしても 良い(MAY)。
*** Shares? (AP5.8)(MAY)
各オブジェクトは shares コレクションを持っても良い(MAY)。
これは、このオブジェクトを object 属性に含む全ての Announce アクティビティの一覧で、
side effect として追加されたものである。
shares コレクションは OrderedCollection または Collection でなければならず(MUST)、
認証ユーザーの権限によってや、認証がないときに適切になるように、 フィルタリングしても良い(MAY)。
*** featured
> "featured":"https://mastodon.juggler.jp/users/tateisu/collections/featured",
(マストドン拡張?) たぶんPinされた投稿
*** url
actor の「プロフィール web ページ」へのリンク
( id の値と同じではない場合)。
*** name
actor の、望ましい「ニックネーム」や「表示名」。
*** summary
ユーザー自身の簡単な要約や経歴
*** icon
ユーザーのプロフィール画像を表現する、画像へのリンクまたは Image オブジェクト
(これはサムネイルかもしれない)。
*** streams (MAY)
関心のある補助的な Collection のリスト。
*** preferredUsername (MAY)
actor を参照するために使われる短いユーザー名; ユニーク性は保証されない。
*** endpoints (MAY)
この actor またはこの actor を参照する誰かにとって有用かもしれない
(典型的にはサーバ/ドメイン単位の) 追加のエンドポイントをマッピングした json オブジェクト。
このマッピングは actor 文書の中で値としてネストしても良いし、
これらの属性を持つ JSON-LD 文書へのリンクでも良い。
endpoints マッピングは以下の属性を含んでいても良い(MAY):
**** proxyUrl (MAY)
actor のクライアントが、 アクセスするのに認証が必要なリモート ActivityStreams
にアクセスするのに 使われる エンドポイント URI。 このエンドポイントを使うには
、クライアントは 要求する ActivityStreams オブジェクトの id の値を持つ
x-www-form-urlencoded id 引数を 投稿する。
**** oauthAuthorizationEndpoint (MAY)
OAuth 2.0 bearer トークン [RFC6749] [RFC6750] が client to server interactions
の認証として使われる場合、 このエンドポイントは、ブラウザ認証ユーザーが新しい認証
グラントを得るための URI を指定する。
**** oauthTokenEndpoint (MAY)
OAuth 2.0 bearer tokens [RFC6749] [RFC6750] が client to server interactions
の認証として使われる場合、 このエンドポイントは、クライアントがアクセストークン
を得るための URI を指定する。
**** provideClientKey (MAY)
Linked Data Signatures と HTTP Signatures が認証と認可として使われている場合、
このエンドポイントはブラウザ認証ユーザーが client to server interactions のための
クライアントの公開鍵を認証する URI を指定する。
**** signClientKey (MAY)
Linked Data Signatures と HTTP Signatures が認証と認可として使われている場合、
このエンドポイントは this endpoint specifies a URI at which a
client key may be signed by the actor's key for a time window to act on behalf of
the actor in interacting with foreign servers.
**** sharedInbox (MAY)
パブリックに宛先指定された アクティビティとフォロワーによって送られたアクティビティ
を 広く配布するために使われる オプションのエンドポイント。
publicInbox エンドポイントは、 パブリックに読み込み可能な、
Public 特殊コレクションを示す オブジェクトを含む OrderedCollection オブジェクトで
あるべきである(SHOULD)。 sharedInbox エンドポイントからの読み込みは、
Public エンドポイントにアドレス指定されていないオブジェクトを
表現してはならない(MUST NOT)。
#########################################################################
* コレクション (AP5)
ActivityPub は大きなオブジェクトの集合を辿るために ActivityStreams paging を使うことに注意すること。
https://www.w3.org/TR/activitystreams-core/#paging
** OrderedCollection 型
OrderedCollection は一貫して逆時系列順で表現されなければならない(MUST)。
** Collection 型
順序が特定されてない
** Publicコレクション
activityの宛先に使える特殊なコレクション指定。
識別子 https://www.w3.org/ns/activitystreams#Public
短い表現 Public および as:Public がある
#########################################################################
* Activity
POST リクエストのボディは、
- 単一の Activity (組み込みオブジェクトを含んでいても良い(MAY))、
- あるいは サーバによって Create アクティビティにラッピングされる 単一の非 Activity オブジェクト
のどちらかを含んでいなければならない(MUST)。
id 属性付きの Activity が投稿されたとき、 サーバはこれを無視してこの Activity のための新しい id を 生成しなければならない(MUST)。
サーバは 201 Created HTTP コードを返さなければならず(MUST)、
Activity が一時的なものでない限り、 Location ヘッダに新しい id を 含めなければならない(MUST)。
ActivityStreams オブジェクトに bto や bcc 属性がある 場合、
- サーバは配送の前にこれらを削除しなければならない(MUST)
- もともと bto / bcc 属性に保管されていた宛先を delivery での宛先を決定するのに使用しなければならない(MUST)。
それからサーバは新しい Activity を outbox コレクションに 追加しなければならない(MUST)。
Activity の型に依存して、サーバはさらなる副作用を実行することが要求される。
(しかし、Activity が outbox に現れる時刻には保証されない。 Activity は遅延して現れたり、任意の時点で消滅したりするかもしれない。)
これらは後述する個々の Activity に記述されている。
** アドレス指定
クライアント は、 新しい Activity を適切にアドレス指定することに責任を持つ。
To some extent, this is dependent upon the particular client implementation,
but clients must be aware that the server will only forward new Activities to addressees in the
to, bto, cc, bcc, and audience fields.
Followers Collection と Public Collection は、 新しい Activity のデフォルトの宛先として良い選択肢である。
INFO: {
"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1",{"manuallyApprovesFollowers":"as:manuallyApprovesFollowers","sensitive":"as:sensitive","movedTo":{"@id":"as:movedTo","@type":"@id"},"Hashtag":"as:Hashtag","ostatus":"http://ostatus.org#","atomUri":"ostatus:atomUri","inReplyToAtomUri":"ostatus:inReplyToAtomUri","conversation":"ostatus:conversation","toot":"http://joinmastodon.org/ns#","Emoji":"toot:Emoji","focalPoint":{"@container":"@list","@id":"toot:focalPoint"},"featured":{"@id":"toot:featured","@type":"@id"},"schema":"http://schema.org#","PropertyValue":"schema:PropertyValue","value":"schema:value"}]
,"id":"https://mastodon.juggler.jp/users/tateisu/outbox"
,"type":"OrderedCollection","totalItems":9500
,"first":"https://mastodon.juggler.jp/users/tateisu/outbox?page=true"
,"last":"https://mastodon.juggler.jp/users/tateisu/outbox?min_id=0\u0026page=true"}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment