Helge's blog

by helge@mymath.rocks

Powered by longhorn, an ActivityPub Client based blog. This means an existing Fediverse account is used to federate blog entries. The entire thing is based on bovine and the corresponding ActivityPub server.

Atom Feed


BIN-5 A Renderable Conversation

When building stuff for the Fediverse there is a lot of stuff not covered in documentation or specification. One such thing is how to pass a conversation from the backend to the frontend to render it. This issue is further made difficult by json-ld being linked data, and thus not being a single thing, but something one can iteratively fetch more of. The approach described here is implemented as a renderer in buffalo-components in React see here.

What is a conversation?

First, when rendering one can safely ignore the CRUD operations (Create, Update, Delete activities) as they contain little meaningful information. So what one is commonly left with are Note, Article, and Page objects. These can be linked together in two ways:

  1. Object two has its inReplyTo property set to the id of object one
  2. Object one contains two in its replies collection

As option 1 is the one used in the Fediverse, we will focus on it.

We can now recursively define the conversation C containing a certain object x:

  1. x is a member of C
  2. y is a member of C if there exists a member z of C with z["inReplyTo"] = y["id"] or y["inReplyTo"] = z["id"]

What this does is define the conversation as including the replies of all it members, and all objects its members reply to. Unfortunately, this one cannot really implement this, so instead of the full conversation, one will usually use the conversation known to a server. Furthermore, additional restrictions might apply like:

One can now represent the conversation as the set of its members. This will commonly be a JSON array. The elements of this array are representations of the ActivityStreams objects.

An element of a conversation

We now detail what we mean by a _representation of the ActivityStreams object. First this means that we are leaving the realm of linked data, as we do not wish to make the front end have to resolve links when rendering.

So in summary, the basic idea is simple: One should include everything that is necessary to render the object. This means that

There are a bunch of corner cases here, e.g. how to support FEP-e232: Object Links. If one wants to properly represent the linked object, one should probably also include it. However, one should not implement these things in a way that leads to infinite recursion.

The same thought applies to the likes collection. One might want to resolve the activities and their actors in order to present a list of who liked an activity. However, one should stop resolving at one point, e.g. not resolve an actor’s outbox.

Further use: Archiving

As the list corresponding to a conversation can be used to render the entire conversation, it can also be used as an archive. When doing so, some care should be taken to include media resources. The above format only includes media resources via a reference.

You can reply to this post using your favorite FediVerse Application. For this look up the object
in it and just reply. Depending on how your FediVerse Application handles Articles, this post may appear different.