@ex @lina @mint В логах однако есть
May 04 13:31:01 houraisan.eientei.org mix[5666]: 13:31:01.485 [error] Could not parse featured collection %{"@context" => ["https://www.w3.org/ns/activitystreams", "https://w3id.org/security/v1", "https://w3id.org/security/data-integrity/v2", %{"Emoji" => "toot:Emoji", "Hashtag" => "as:Hashtag", "sensitive" => "as:sensitive", "toot" => "http://joinmastodon.org/ns#"}], "first" => "https://unseen.name/users/ex/collections/featured?page=true", "id" => "https://unseen.name/users/ex/collections/featured", "type" => "OrderedCollection"} May 04 15:12:00 houraisan.eientei.org mix[5666]: 15:12:00.037 [error] Publisher failed to inbox https://unseen.name/users/ex/inbox {:error, :checkout_timeout}но в очередях уже ничего нет
select count(*) from oban_jobs where queue = 'federator_incoming' and args::text like '%unseen.name%' ; count ------- 0 (1 row)@silverpill it looks like my mitra instance cannot follow the relay using AodeRelay. I see some error messages in the logs.
Oct 12 05:03:03 grassland mitra[1880146]: 2025-10-12T05:03:03 mitra_activitypub::queues [INFO] delivering activity to 1 inboxes: {"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1","https://w3id.org/security/data-integrity/v1",{"Emoji":"toot:Emoji","EmojiReact":"litepub:EmojiReact","Hashtag":"as:Hashtag","litepub":"http://litepub.social/ns#","sensitive":"as:sensitive","toot":"http://joinmastodon.org/ns#"}],"actor":"https://moon.lonewolf.zone/users/followbot","id":"https://moon.lonewolf.zone/activities/follow/0199d655-f659-3d21-bd61-1fd771736447","object":"https://relay.synth.download/actor","proof":{"created":"2025-10-12T02:53:01.917253640Z","cryptosuite":"eddsa-jcs-2022","proofPurpose":"assertionMethod","proofValue":"z2xPPCkL8WiCDZu7BcFMJpMZVFtgDMZk8V5ysvDYyxNdnx3N8e4VCA8eYPAa6X8HKWaPNEkiPBAWWk4jGaQimErVa","type":"DataIntegrityProof","verificationMethod":"https://moon.lonewolf.zone/users/followbot#ed25519-key"},"to":["https://relay.synth.download/actor"],"type":"Follow"} Oct 12 05:03:13 grassland mitra[1880146]: 2025-10-12T05:03:13 mitra_activitypub::deliverer [WARN] failed to deliver activity to https://relay.synth.download/inbox: error sending request for url (https://relay.synth.download/inbox): operation timed outsometimes it returns 400 error.
Oct 12 05:02:35 v2202502232422317350 mitra[1880146]: 2025-10-12T05:02:35 mitra_activitypub::deliverer [WARN] failed to deliver activity to https://relay.synth.download/inbox: HTTP error 400: [400]次のような未知のJSONがソフトウェアに与えられたとき、
{
"name": "Alice"
}
ソフトウェアは"Alice"という値がなんであるかを識別することはできません。よって、nameという文字列キーの代わりに事前に定義された識別子を用いることにしましょう。例えば:
{
"http://xmlns.com/foaf/0.1/name": "Alice"
}
(URLとして解釈可能な文字列ではありますが、これはたまたまです。URLとして機能するわけではありません。便宜上このような文字列を使っているというだけ。ですのでそのURLのドメインが悪意ある第三者によって詐欺サイトにリダイレクトするようになっていても、JSON-LD的には問題ありません!)
ここで、互換性のため@contextというものを考えたいと思います。これを使って次のように書くと、
{
"@context": {
"name": "http://xmlns.com/foaf/0.1/name"
},
"name": "Alice"
}
@contextを無視するだけで、従来のソフトウェアは今まで通りにJSONを扱うことができます。これがJSON-LDの基本的なコンセプトです。
ちなみに@contextではあらゆる識別子をあらゆる文字列へマッピングできます。よって、ソフトウェアは次の2種類のJSON-LDを同じように解釈する必要がありますね!
{
"@context": {
"name": "http://xmlns.com/foaf/0.1/name"
},
"name": "Alice"
}{
"@context": {
"名前": "http://xmlns.com/foaf/0.1/name"
},
"名前": "Alice"
}
ではここでさらなる抽象化を考えてみましょう。次のようにすると、与えられたJSON-LDが人物の情報であることを表すことができます。
{
"@context": "https://json-ld.org/contexts/person.jsonld",
"name": "Alice"
}
コンテキストは複数指定することもできますし、従来の辞書型と混ぜることもできます。さらに、あるコンテキストで定義されたキーに別名を付けて使うこともできます。
{
"@context": [
"https://example.com/foo",
"https://example.com/bar",
{
"buz": "https://example.com/buz",
"qux": "buz:qux"
}
]
}
そうそう、クラス定義というものもあります。次の例における"Object"という文字列値は、Activity Vocabulary(ActiviyPubを構成する仕様の一つ)におけるObjectというクラスであることを示すものです。
{
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Object",
"id": "http://www.test.example/object/1",
"name": "A Simple, non-specific object"
}
Objectという文字列がキーとして使われることがないことはJSON-LDからは読み取れませんが、まあなんとかしてください!
ちなみにMisskeyが送信するJSONに付与する@contextは次の通り。つまり、このコンテキストを理解できるソフトウェアを作れば、Misskeyと連携することができるということです。
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://w3id.org/security/v1",
{
"Key": "sec:Key",
"manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
"sensitive": "as:sensitive",
"Hashtag": "as:Hashtag",
"quoteUrl": "as:quoteUrl",
"toot": "http://joinmastodon.org/ns#",
"Emoji": "toot:Emoji",
"featured": "toot:featured",
"discoverable": "toot:discoverable",
"schema": "http://schema.org#",
"PropertyValue": "schema:PropertyValue",
"value": "schema:value",
"misskey": "https://misskey-hub.net/ns#",
"_misskey_content": "misskey:_misskey_content",
"_misskey_quote": "misskey:_misskey_quote",
"_misskey_reaction": "misskey:_misskey_reaction",
"_misskey_votes": "misskey:_misskey_votes",
"_misskey_summary": "misskey:_misskey_summary",
"isCat": "misskey:isCat",
"vcard": "http://www.w3.org/2006/vcard/ns#"
}
]
}
(ですがMisskeyは受信したJSON-LDをただのJSONとして解釈し、@contextの内容は関知しません。)
そもそも情報交換用のサーバ間APIでJSON-LDのような柔軟で既存のJSON構造を壊さずに導入できる仕様を使う必要はないかもしれませんが……まあ細かいことは気にしない!
それでは、楽しいActivityPubサーバ開発を!!!
This is an activity I received:
{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1","https://www.w3.org/ns/did/v1","https://w3id.org/security/multikey/v1","https://w3id.org/security/data-integrity/v1","https://w3id.org/fep/c390",{"Category":"nomad:Category","Hashtag":"as:Hashtag","Sync":"nomad:Sync","canReply":"toot:canReply","canSearch":"nomad:canSearch","collectionOf":"nomad:collectionOf","contextHistory":{"@container":"@list","@id":"https://w3id.org/fep/171b/contextHistory","@type":"@id"},"copiedTo":"nomad:copiedTo","directMessage":"nomad:directMessage","discoverable":"toot:discoverable","expires":"nomad:expires","gateways":{"@container":"@list","@id":"https://w3id.org/fep/ef61/gateways","@type":"@id"},"indexable":"toot:indexable","joinMode":"https://w3id.org/fep/8a8e/joinMode","manuallyApprovesFollowers":"as:manuallyApprovesFollowers","movedTo":"as:movedTo","nomad":"https://macgirvin.com/apschema#","oauthRegistrationEndpoint":"nomad:oauthRegistrationEndpoint","openWebAuth":"nomad:openWebAuth","owaRedirect":"nomad:owaRedirect","permissions":"nomad:permissions","searchContent":"nomad:searchContent","searchTags":"nomad:searchTags","sensitive":"as:sensitive","timezone":"http://www.w3.org/2006/time#timezone","toot":"http://joinmastodon.org/ns#","webfinger":{"@id":"wf:webfinger","@type":"xsd:string"},"wf":"https://purl.archive.org/socialweb/webfinger#","xsd":"http://www.w3.org/2001/XMLSchema#"}],"actor":"https://macgirvin.com/.well-known/apgateway/did🔑z6MkhPXNfiHDh2qSNjFzZ9yY27C1iHnHVbb1eaxuoiEe4tjk/actor","cc":[],"context":"https://macgirvin.com/.well-known/apgateway/did🔑z6MkhPXNfiHDh2qSNjFzZ9yY27C1iHnHVbb1eaxuoiEe4tjk/conversation/history/3f3e6efe-9bac-425d-9692-4df179937c5f","contextHistory":"https://macgirvin.com/.well-known/apgateway/did🔑z6MkhPXNfiHDh2qSNjFzZ9yY27C1iHnHVbb1eaxuoiEe4tjk/conversation/history/3f3e6efe-9bac-425d-9692-4df179937c5f","directMessage":true,"id":"https://macgirvin.com/.well-known/apgateway/did🔑z6MkhPXNfiHDh2qSNjFzZ9yY27C1iHnHVbb1eaxuoiEe4tjk/activity/3f3e6efe-9bac-425d-9692-4df179937c5f","object":{"attributedTo":"https://macgirvin.com/.well-known/apgateway/did🔑z6MkhPXNfiHDh2qSNjFzZ9yY27C1iHnHVbb1eaxuoiEe4tjk/actor","canReply":["https://macgirvin.com/.well-known/apgateway/did🔑z6MkhPXNfiHDh2qSNjFzZ9yY27C1iHnHVbb1eaxuoiEe4tjk/actor/followers"],"cc":[],"content":"@!<span class=\"h-card\"><a class=\"u-url mention\" href=\"https://mitra.social/users/silverpill\" target=\"_blank\" rel=\"nofollow noopener\" >silverpill@mitra.social</a></span> Here's an activity that should be signed with RFC9421.","context":"https://macgirvin.com/.well-known/apgateway/did🔑z6MkhPXNfiHDh2qSNjFzZ9yY27C1iHnHVbb1eaxuoiEe4tjk/conversation/history/3f3e6efe-9bac-425d-9692-4df179937c5f","contextHistory":"https://macgirvin.com/.well-known/apgateway/did🔑z6MkhPXNfiHDh2qSNjFzZ9yY27C1iHnHVbb1eaxuoiEe4tjk/conversation/history/3f3e6efe-9bac-425d-9692-4df179937c5f","directMessage":true,"id":"https://macgirvin.com/.well-known/apgateway/did🔑z6MkhPXNfiHDh2qSNjFzZ9yY27C1iHnHVbb1eaxuoiEe4tjk/item/3f3e6efe-9bac-425d-9692-4df179937c5f","proof":{"created":"2025-06-09T21:22:04Z","cryptosuite":"eddsa-jcs-2022","proofPurpose":"assertionMethod","proofValue":"zcxM3mfRbyXsbNx3YZypxjMPhVxcBuyo6Lz6ZUz9hmHaEok7mfG9Db9oA8uz9LWzF7EZnHHKKBn5UuM81FNmXPDo","type":"DataIntegrityProof","verificationMethod":"did🔑z6MkhPXNfiHDh2qSNjFzZ9yY27C1iHnHVbb1eaxuoiEe4tjk"},"published":"2025-06-09T21:22:04Z","replies":"https://macgirvin.com/.well-known/apgateway/did🔑z6MkhPXNfiHDh2qSNjFzZ9yY27C1iHnHVbb1eaxuoiEe4tjk/replies/3f3e6efe-9bac-425d-9692-4df179937c5f","source":{"content":"@![url=https://mitra.social/users/silverpill]silverpill[/url] Here's an activity that should be signed with RFC9421.","mediaType":"text/x-multicode"},"tag":[{"href":"https://mitra.social/users/silverpill","name":"@silverpill@mitra.social","type":"Mention"}],"to":["https://mitra.social/users/silverpill"],"type":"Note","url":"https://macgirvin.com/.well-known/apgateway/did🔑z6MkhPXNfiHDh2qSNjFzZ9yY27C1iHnHVbb1eaxuoiEe4tjk/item/3f3e6efe-9bac-425d-9692-4df179937c5f"},"proof":{"created":"2025-06-09T21:22:05Z","cryptosuite":"eddsa-jcs-2022","proofPurpose":"assertionMethod","proofValue":"z5tDnWHWDj2JyaA3CHAcDe3Qy3K77HtSMrAGsucSk6pbp3bsbuUU8cZR5NkQyfE273JgT9FwYaCrtTAXUN4oJocNQ","type":"DataIntegrityProof","verificationMethod":"did🔑z6MkhPXNfiHDh2qSNjFzZ9yY27C1iHnHVbb1eaxuoiEe4tjk"},"published":"2025-06-09T21:22:04Z","tag":[{"href":"https://mitra.social/users/silverpill","name":"@silverpill@mitra.social","type":"Mention"}],"target":{"attributedTo":"https://macgirvin.com/.well-known/apgateway/did🔑z6MkhPXNfiHDh2qSNjFzZ9yY27C1iHnHVbb1eaxuoiEe4tjk/actor","id":"https://macgirvin.com/.well-known/apgateway/did🔑z6MkhPXNfiHDh2qSNjFzZ9yY27C1iHnHVbb1eaxuoiEe4tjk/conversation/history/3f3e6efe-9bac-425d-9692-4df179937c5f","type":"Collection"},"to":["https://mitra.social/users/silverpill"],"type":"Create","url":"https://macgirvin.com/.well-known/apgateway/did🔑z6MkhPXNfiHDh2qSNjFzZ9yY27C1iHnHVbb1eaxuoiEe4tjk/activity/3f3e6efe-9bac-425d-9692-4df179937c5f"}I can verify the activity, but not its object.
Canonicalized object (with proof taken out):
{"attributedTo":"https://macgirvin.com/.well-known/apgateway/did🔑z6MkhPXNfiHDh2qSNjFzZ9yY27C1iHnHVbb1eaxuoiEe4tjk/actor","canReply":["https://macgirvin.com/.well-known/apgateway/did🔑z6MkhPXNfiHDh2qSNjFzZ9yY27C1iHnHVbb1eaxuoiEe4tjk/actor/followers"],"cc":[],"content":"@!<span class=\"h-card\"><a class=\"u-url mention\" href=\"https://mitra.social/users/silverpill\" target=\"_blank\" rel=\"nofollow noopener\" >silverpill@mitra.social</a></span> Here's an activity that should be signed with RFC9421.","context":"https://macgirvin.com/.well-known/apgateway/did🔑z6MkhPXNfiHDh2qSNjFzZ9yY27C1iHnHVbb1eaxuoiEe4tjk/conversation/history/3f3e6efe-9bac-425d-9692-4df179937c5f","contextHistory":"https://macgirvin.com/.well-known/apgateway/did🔑z6MkhPXNfiHDh2qSNjFzZ9yY27C1iHnHVbb1eaxuoiEe4tjk/conversation/history/3f3e6efe-9bac-425d-9692-4df179937c5f","directMessage":true,"id":"https://macgirvin.com/.well-known/apgateway/did🔑z6MkhPXNfiHDh2qSNjFzZ9yY27C1iHnHVbb1eaxuoiEe4tjk/item/3f3e6efe-9bac-425d-9692-4df179937c5f","published":"2025-06-09T21:22:04Z","replies":"https://macgirvin.com/.well-known/apgateway/did🔑z6MkhPXNfiHDh2qSNjFzZ9yY27C1iHnHVbb1eaxuoiEe4tjk/replies/3f3e6efe-9bac-425d-9692-4df179937c5f","source":{"content":"@![url=https://mitra.social/users/silverpill]silverpill[/url] Here's an activity that should be signed with RFC9421.","mediaType":"text/x-multicode"},"tag":[{"href":"https://mitra.social/users/silverpill","name":"@silverpill@mitra.social","type":"Mention"}],"to":["https://mitra.social/users/silverpill"],"type":"Note","url":"https://macgirvin.com/.well-known/apgateway/did🔑z6MkhPXNfiHDh2qSNjFzZ9yY27C1iHnHVbb1eaxuoiEe4tjk/item/3f3e6efe-9bac-425d-9692-4df179937c5f"}Signature base (object and proof config hashes):
3e51edddfe2378d071b6a79f091150b035045e80d053ce180893f000c5fba50197b90ed2cf47016298ae77a9a8572ba32c39e0570aa31c85033f54525af733bbso what do you actually lose out on when you ignore json-ld context?
you first have to fall back to the "implicit context", where AS2 terms are generally agreed upon, but nothing else is guaranteed.
take something like `discoverable` from mastodon. what does it mean? well, it means whatever is defined in the mastodon codebase and documentation. so we could represent that as http://joinmastodon.org/ns#discoverable or shorten that with a prefix. but if we do, then most #fediverse will choke on that.
24/?
@hongminhee Yes, it should be able to verify proofs with injected @context. But it is not injected. Here' the Announce activity, for example:
{ "@context": [ "https://www.w3.org/ns/activitystreams", "https://w3id.org/security/data-integrity/v1", { "Emoji": "toot:Emoji", "Hashtag": "as:Hashtag", "sensitive": "as:sensitive", "toot": "http://joinmastodon.org/ns#" } ], "actor": "https://hollo.social/@fedify", "cc": [ "https://fosstodon.org/users/hongminhee", "https://hollo.social/@fedify/followers", "https://fosstodon.org/users/hongminhee" ], "id": "https://hollo.social/@fedify/01905d94-a20b-7722-94d1-576817dd3b00#activity", "object": "https://fosstodon.org/users/hongminhee/statuses/112692842178962546", "proof": { "created": "2024-06-28T06:58:47.16192715Z", "cryptosuite": "eddsa-jcs-2022", "proofPurpose": "assertionMethod", "proofValue": "z4xV1JV4JFuoPcLBNBTDbkceyPdd3YGWdFU4oawZDX5qSxiKeJgjFMf3uwf71QCfNUmJay66g9556K6NjUUUxZu1g", "type": "DataIntegrityProof", "verificationMethod": "https://hollo.social/@fedify#key-2" }, "published": "2024-06-28T06:42:20.3Z", "to": "as:Public", "type": "Announce" }GNU social JP is a social network, courtesy of GNU social JP管理人. It runs on GNU social, version 2.0.2-dev, available under the GNU Affero General Public License.
All GNU social JP content and data are available under the Creative Commons Attribution 3.0 license.