wiki.trwnh.com/content/tech/spec/activitypub/!gotchas.md

3.1 KiB

+++ +++

Gotchas

{{}}

DO NOT VALIDATE @CONTEXT IF YOU DO NOT UNDERSTAND JSON-LD

you CANNOT check for the presence of https://www.w3.org/ns/activitystreams AT ALL -- the activitystreams context may be included within another context hosted elsewhere. just ignore this property entirely if you don't understand it

DON'T BE STRICT ABOUT VALIDATING ID

do NOT try to be overly strict about dereferencing IDs. some IDs may not be on your domain, or otherwise they may not be present at all, or they may be explicitly null. null or missing id indicates a transient activity.

example: Follow semantics

Follows are realistically transient. it is therefore enough to:

  • keep track of local state
  • mutate state based on activities

if you receive an Accept/Reject Follow, check ONLY for the following:

  • actor
  • type == Accept/Reject
  • object.actor
  • object.type == Follow
  • object.object == actor

if object is inlined, you don't need to check that object.id is local. the above is enough information, PROVIDED THAT you have a local pending follow request. if you do not have a pending follow, then DO NOT process an incoming Accept Follow. however, you may receive a Reject Follow at any time, indicating that you should destroy that follow relationship. note that you may also receive an Undo Accept Follow by some implementations. this is discouraged but should be handled as well

https://github.com/misskey-dev/misskey/issues/9250

DO NOT CHECK TYPES DURING VALIDATION

an Actor has an inbox and outbox. that's it.

an Activity has an actor. that's it.

a Collection has items or orderedItems. that's it.

etc

DON'T PANIC WHEN YOU SEE A TYPE YOU DON'T UNDERSTAND

say you understand tags of type Mention and Hashtag and Emoji. someone sends you a tag array with a raw Link. DON'T PANIC. the document is still valid. just filter out anything you don't understand, something like

UNDERSTOOD_TAG_TYPES = set("Mention", "Hashtag", "Emoji")
document = json.loads(...)
tags = document.get('tag', [])
tags = [
	tag
	for tag in tags
	if tag['type'] in UNDERSTOOD_TAG_TYPES
]
# do whatever you need to now
const UNDERSTOOD_TAG_TYPES = new Set(["Mention", "Hashtag", "Emoji"])
let document = ...
tags = document.tag.filter(tag => tag.type in UNDERSTOOD_TAG_TYPES)
// do whatever you need to now

DO NOT CONFUSE ITEMS AND ORDEREDITEMS

items indicates that this is a Collection

however, orderedItems is valid on both Collection and OrderedCollection! it is defined like this in the as2 context:

"orderedItems": {
	"@id": "as:items",
	"@type": "@id",
	"@container": "@list"
}

so it is basically just an alias for items where it MUST be an array, and the array's order matters. (if it were @container: set, then it MUST be an array, but the array's order does not matter.)

tangent: a Collection may be ordered without being an OrderedCollection

OrderedCollection is defined as strictly reverse chronological by ActivityPub. however, other orderings are valid on regular Collections. the use of the orderedItems term allows plain-JSON implementations to do exactly this.