14 KiB
Activity
an Activity is just an object that has an actor
. it represents an action that was performed.
{{}}
activities in activitypub
activities are meant to be POSTed to the outbox in C2S (by the Client), then if the Server is also a Federated Server, they get delivered to recipients' inboxes via POST to inbox (by the Federated Server)
for C2S: if it has actor
then do not wrap it in a Create when it gets POSTed to outbox. otherwise, per [AP § 6.2.1 "Object creation without a Create Activity"]:
- make a new
Create
to wrap the object inobject
- copy over
to
/cc
/bto
/bcc
/audience
from the object to the activity. - [not explicitly stated:] set
actor
on the activity equal to the current authorized user, then copy that over toobject.attributedTo
- generate an
id
for both theCreate
and theobject
, unless it is transient [[how do we determine this? perhaps a client explicitly specifiesid=null
?]] - return the
id
of the activity via theLocation
header
for S2S: check to
/cc
/bto
/bcc
/audience
on the activity. dereference any collections with a recursion limit (possibly n=1). add all discovered inboxes to a list. remove bto
/bcc
. POST to the list of discovered inboxes.
some activity types have side-effects defined in the activitypub spec, sections 6 (c2S) and 7 (s2s)
(any Activity)
if it has actor
then do not wrap it in a Create when it gets POSTed to outbox
- C2S: MUST assign
id
to the activity, ignoring anything that might be set by the Client, unless it is transient how to determine this? - C2S: add it to the current actor's outbox if not transient?
- C2S: Return HTTP
201 Created
,Location: <id>
- S2S: warning, if it's an extension activity type then its side effects may not be understood. there may be fallback strategies to display
name
/summary
/content
Create
Update
Delete
Add
Remove
Follow
Like
Block (C2S only)
Announce (S2S only)
Accept (S2S only)
Reject (S2S only)
Undo
activities in the fediverse
in practice and in actuality, the "fediverse" largely does not conform to any of the 3 activitypub profiles. because c2s is not used, there are basically no Clients or Servers. and even on the s2s side, the side effects described by activitypub are not applied in any meaningful way. the real side effects vary per project. it can be argued that the fediverse is actually not built on activitypub, but rather, it is built on activitystreams 2.0 + linked data notifications. (it is a little-known fact that the inbox
property in activitypub is actually ldp:inbox
as defined by the linked data platform.)
mastodon
supported activity types https://github.com/mastodon/mastodon/tree/main/app/lib/activitypub/activity
- Accept (accept a follow request)
- Add (adds hashtag or status to featured collection)
- Announce (reblog a status)
- Block (block an account)
- Create (create a message or status)
- Delete (delete account or status)
- Flag (report accounts and/or statuses)
- Follow (request to follow a local account)
- Like (favourite a status)
- Move (migrate an account's followers)
- Reject (reject follow request or remove follower)
- Remove (removes hashtag or status from featured collection)
- Undo (undoes some activities if possible)
- Update (update account info or edit a status)
extended logic
- Accept
- Accept Follow -- authorize a follow request
- (when relay is findable by
object
as follow_activity_id) - (when
object
is uri of existing follow request) - (when
object
is embedded Follow)- Accept Follow
<Account>
- Accept Follow
- (when relay is findable by
- Accept Follow -- authorize a follow request
- Add
- (must have
target
) - (
target
must be atoot:featured
collection) - (
object
must be inlined?) - Add Hashtag to
target<featured>
-- feature a hashtag- (takes
object.name
and removes prefix#
) - (creates FeaturedTag entity for the
actor
's account)
- (takes
- Add
object<Status>
totarget<featured>
-- pin a status- (
object
must be transformable to status) - (status must be authored by
actor
) - (status must not already be pinned)
- (
- (must have
- Announce
- (must be related to local activity)
- (i.e.
actor<Account>
followed by local accounts) - (or requested through relay)
- (or
object
refers to a status whose account is local)
- (i.e.
- (
object
resolves to a status) - Announce
object<Status>
-- creates a reblog of a status- (stop if:)
- (no status)
- (status not boostable)
- (requested through relay)
- (find existing reblog or create)
- (stop if:)
- (must be related to local activity)
- Block
- (
object
resolves to an account)- (the resolved account exists and is local)
- Block
object<Account>
-- block an account- (unfollow the
object<Account>
) - (force
object<Account>
to unfollow you) - (reject any follow requests from
object<Account>
) - (create a block asynchronously)
- (unfollow the
- (
- Create
- (dereference the
object
) - Create EncryptedMessage -- creates an encrypted message
- (tries to find a device id)
- (extracts
messageType
,cipherText
,digest
,messageFranking
)
- Create
object<Status>
-- creates a status- (rejected if)
- (unsupported object type)
- (
object
is a string) - (not in supported types)
- Note
- Question
- (not in converted types)
- Image
- Audio
- Video
- Article
- Page
- Event
- (
- (or invalid origin)
- (or tombstone exists for
object
uri) - (or not related to local activity)
- (unsupported object type)
- (rejected if)
- (dereference the
- Delete
- (if
actor
matchesobject
)- Delete
object<Account>
-- delete your own account
- Delete
- Delete
object<Status>
-- delete a status- (create tombstone unless origin is invalid)
- (forward deletion if forwardable)
- (remove status from database and timelines)
- (if
- Flag
- (
object
array is resolved as accounts and statuses)- (then filtered for local)
- Flag
object<Account,Status>
-- report an account and/or statuses- (foreach account get reported statuses)
- (create a report against the account w/ optional status ids and content)
- (
- Follow
- (
object
must be a local account that exists) - Follow
object<Account>
-- request to follow a local account- (create or update follow request)
- (auto-reject if:)
- (
object<Account>
is blockingactor<Account>
) - (
object<Account>
is domain-blockingactor
's domain) - (
object<Account>
has moved/redirected) - (
object<Account>
is the instance actor)
- (
- (send an Accept Follow if a follow already exists)
- (otherwise create a follow request)
- (if you are silenced or they are locked, send frq notification)
- (otherwise send Accept Follow and follow notification)
- (
- Like
- (resolve status from
object
) - Like
object<Status>
-- favourite a status- (stop if:)
- (no status resolved)
- (status is not from a local account)
- (delete arrived first)
- (you already favourited this status)
- (create a favourite by
actor<Account>
forobject<Status>
)
- (stop if:)
- (resolve status from
- Move
- (
actor
must matchobject
and resolve to account) - (resolve
target
as account) - Move
object<Account>
totarget<Account>
-- migrate your followers- (stop if:)
- (no
target<Account>
) - (
target<Account>
is suspended) - (
target.alsoKnownAs
doesn't includeobject
)
- (no
- (set a redirect)
- (async move followers from
object<Account>
totarget<Account>
)
- (stop if:)
- (
- Reject
- Reject Follow -- reject a follow request or remove follower
- (when relay is findable by
object
as follow_activity_id) - (when
object
is uri of existing follow request) - (when
object
is uri of existing follow)- (call UnfollowService for
actor<Account>
)
- (call UnfollowService for
- (when
object
is embedded Follow)- Reject Follow
Follow.object<Account>
- Reject Follow
- (when relay is findable by
- Reject Follow -- reject a follow request or remove follower
- Remove
- (must have
target
) - (
target
must be atoot:featured
collection) - (
object
must be inlined?) - Remove Hashtag from
target<featured>
-- unfeature a hashtag- (takes
object.name
and removes prefix#
) - (deletes FeaturedTag entity for the
actor
's account)
- (takes
- Remove
object<Status>
fromtarget<featured>
-- unpin a status- (
object
must be transformable to status) - (status must be authored by
actor
) - (destroy pin if existing pin found)
- (
- (must have
- Undo
- (
object
should be inlined or else it may not be handled) - Undo Announce -- unreblog a status
- (stop if no
Announce.id
) - (resolve
Announce.id
as status reblog) - (call RemoveStatusService on status)
- (stop if no
- Undo Accept -- unfollow an account [yes this is the assumption]
- (find follow by
object.object.id
and revoke it)
- (find follow by
- Undo Follow
- (resolve
object.object
as account)- (stop if not exists or not local)
- Undo Follow
<Account>
-- unfollow an account- (
Undo.actor
unfollowsFollow.object<Account>
if following)
- (
- (resolve
- Undo Like
- (resolve
object.object
as status) - (stop if no status or if status is not local)
- Undo Like
<Status>
-- unfavourite a status- (if
actor
has favourited the status:)- (find a favourite on that status by that account)
- (destroy it)
- (if
- (resolve
- Undo Block
- (resolve
object.object
as account) - (stop if not exists or not local)
- Undo Block
<Account>
--unblock an account- (call UnblockService if
actor
is blockingBlock.object<Account>
)
- (call UnblockService if
- (resolve
- Undo
object<IRI>
- (try_undo_announce)
- (find reblogged status by
object
uri andactor
) - (if found, remove reblog and stop, else continue)
- (find reblogged status by
- (try_undo_accept)
- (do nothing, continue) [because Accept uri is not stored]
- (try_undo_follow)
- (find
actor<Account>
follow request/relation byobject
uri) - (if found, destroy it and stop, else continue)
- (find
- (try_undo_like)
- (do nothing, continue) ["too costly", no index by Like uri]
- (try_undo_block)
- (find
actor<Account>
block byobject
uri) - (if found, call UnblockService and stop, else continue)
- (find
- (try_undo_announce)
- (
- Update
- (dereference
object
) - (if
object.type
inApplication Group Organization Person Service
)- Update
object<Account>
-- update an account's info- (stop if
actor.id
does not matchobject.id
) - (call ProcessAccountService)
- (stop if
- Update
- (else if
object.type
inNote Question
)- Update
object<Status>
-- edit a status- (stop if invalid origin)
- (resolve
object
as status) - (stop if no status)
- (call ProcessStatusUpdateService)
- Update
- (dereference
pixelfed
https://github.com/pixelfed/pixelfed/blob/dev/app/Util/ActivityPub/Inbox.php
(seems to require inlining in a lot of places? not 100% sure but that's what it looks like to me)
- Add
- (must be inlined?)
- Add Story (not final)
- Create
- (requires
to
for some reason, socc
only will break) - Create Question
- (a single
to
item will create a DM if nocc
) - Create Note.inReplyTo
- Create Note.attachment
- (requires
- Follow
- Follow
object<Profile>
- Follow
- Announce
- Announce
object<Status>
- Announce
- Accept
- Accept Follow (anything else will return immediately)
- Delete
- Delete
object<Profile>
(ifobject
==actor
and is valid string uri) - Delete [Person, Tombstone, Story] (???)
- Delete Person
- Delete Tombstone (???)
- Delete Story (not final)
- Delete
- Like
- Like
object<Status>
- Like
- Reject
- (does nothing)
- Undo
- (must be inlined)
- Undo Accept
- (does nothing)
- Undo Announce
- Undo Block
- (does nothing)
- Undo Follow
- Undo Like
- View
- View Story (not final)
- (also seems to get story id by whatever is after the last slash?)
- View Story (not final)
- Story:Reaction (not final; undocumented extension)
- (
id
andactor
must be valid urls) - (
inReplyTo
andto
must be local) - (
object
must not resolve to Status) - (seems to get story id by whatever is after the last slash?)
- (
- Story:Reply (not final; undocumented extension)
- (
id
andactor
must be valid urls) - (
inReplyTo
andto
must be local) - (
object
must not resolve to Status) - (seems to get story id by whatever is after the last slash?)
- (
- Update (commented out)
misskey
https://github.com/misskey-dev/misskey/blob/develop/packages/backend/src/core/activitypub/type.ts
- Create
- Delete
- Update
- Read
- Undo
- Follow
- Accept
- Reject
- Add
- Remove
- Like | EmojiReaction | EmojiReact
- Announce
- Block
- Flag
pleroma
ObjectValidator https://git.pleroma.social/pleroma/pleroma/-/blob/develop/lib/pleroma/web/activity_pub/object_validator.ex
validate()
- Block
- Undo
- Delete
- Create ChatMessage
- Create [Question Answer Audio Video Event Article Note Page]
- [Event Question Audio Video Article Note Page]
- Event
- Question
- Audio
- Video
- Article
- Note
- Page
- Update [Question Answer Audio Video Event Article Note Page]
- [Accept Reject Follow Update Like EmojiReact Announce]
- Accept
- Reject
- Follow
- Update
- Like
- EmojiReact
- Announce
- ChatMessage
- Answer
- [Add Remove]
SideEffects https://git.pleroma.social/pleroma/pleroma/-/blob/develop/lib/pleroma/web/activity_pub/side_effects.ex
handle()
- Accept
- Accept Follow
- Reject
- Reject Follow
- Follow
- Block
- Update
- Update
object<User>
- Update
object<Object>
- Update
- Like
- Create
- Create ChatMessage
- Create Question
- Create Answer
- Create [Audio Video Event Article Note Page]
- Announce
- Undo
- Undo Like
- Undo EmojiReact
- Undo Announce
- Undo Block
- EmojiReact
- Delete
- Add
- Remove
Transmogrifier https://git.pleroma.social/pleroma/pleroma/-/blob/develop/lib/pleroma/web/activity_pub/transmogrifier.ex
handle_incoming()
- Flag
- Listen Audio
- Like._misskey_reaction
- Create [Question Answer ChatMessage Audio Video Event Article Note Page]
- [Like EmojiReact Announce Add Remove]
- (fetch
actor
andobject
)
- (fetch
- [Update Block Follow Accept Reject]
- (fetch
actor
)
- (fetch
- Delete
- (check if Create exists)
- Undo Follow
- Undo
- (get
object
byid
and expand it)
- (get
- Move
prepare_outgoing()
- [Create Listen]
- Update
object<updatable>
- [Note Question Audio Video Event Article Page]
- Announce
- Accept -> Accept Follow
- Reject -> Reject Follow
- Answer -> Note