Skip to content

ActivityPub based SkoHub

Adrian edited this page Oct 24, 2019 · 18 revisions

On this wiki page we reflect on the details for implementing #16 Switch to ActivityPub for subscriptions.

General approach

Actors

SkoHub assumes three actors (all human or applications) for pubsub:

  1. Each concept in a concept scheme is also typed as as:Service and gets an inbox and an outbox.
  2. A publisher wants to announce a resource via SkoHub by addressing a concept. Each publisher has to be one of five ActivityStreams types of actor and declare an inbox and outbox.
  3. A subscriber follows one or more concepts to get notifications about new resources referencing them. Each subscriber has to be one of five ActivityStreams types of actor and declare an inbox and outbox.

N.B. To be clear, publishers/subscribers are not be managed by SkoHub but by external applications.

Activities

For publication and subscription via SkoHub, the following ActivityPub mechanisms are used:

  1. Subscription to a concept is done with the as:Follow activity.
  2. Publishers will address a concept their resource is about using as:to/as:cc and an as:tag object of type as:Mention.
  3. Concepts will inform their followers with an as:Announce having an Activity mentioning them as as:object.

Examples

Actors

Concept

{
   "@context":{
      "@vocab": "http://www.w3.org/ns/activitystreams#",
      "skos":"http://www.w3.org/2004/02/skos/core#"
    },
   "id":"http://w3id.org/class/hochschulkompass/S79#",
   "name":"Informationstechnik",
   "skos:prefLabel":"Informationstechnik",
   "type":[
      "skos:Concept"
   ],
   "skos:broader": "http://w3id.org/class/hochschulkompass/B74#",
   "skos:inScheme": "http://w3id.org/class/hochschulkompass/scheme#",
   "inbox":"https://skohub.io/inbox?actor=http://w3id.org/class/hochschulkompass/S79#",
   "outbox":"https://skohub.io/outbox?actor=http://w3id.org/class/hochschulkompass/S79#",
   "followers": "https://skohub.io/followers?subject=http://w3id.org/class/hochschulkompass/S79#"
}

Notes:

  • As noted above, besides the inbox/outbox statements, the type as:Service is added to each concept.
  • The use of subject is temporary for the parameter to indicate the concept or element of a KOS the inbox/outbox belongs to. There are probably better name choices.

Publisher

A person as example publisher.

{
   "@context":"https://www.w3.org/ns/activitystreams#",
   "type":"Person",
   "id":"http://example.org/user/124",
   "following":{
      "summary":"Teacher A's Following Collection",
      "type":"Collection",
      "totalItems":0,
      "items":[
      ]
   },
   "inbox":"https://example.org/user/alice/inbox",
   "outbox":"https://example.org/user/alice/outbox",
   "preferredUsername":"Teacher A"
}

Subscriber

An application as example subscriber. Both as:Service and as:Application exist. In this example as:Service is used for an example indexing service that drives a discovery service for IT-related material.

{
   "@context":"https://www.w3.org/ns/activitystreams#",
   "type":"Service",
   "id":"https://example.org/service/123",
   "following":{
     "summary":"Indexing Service's Following Collection",
      "type":"Collection",
      "totalItems":1,
      "items":[
         "http://lobid.org/gnd/7742327-6"
      ]
   },
   "inbox":"https://example.org/service/123/inbox",
   "outbox":"https://example.org/service/123/outbox",
   "preferredUsername":"Informatik Indexing Service"
}

Activities

Subscription with Follow Activity

See also https://www.w3.org/TR/activitypub/#follow-activity-outbox.

{
   "@context":"https://www.w3.org/ns/activitystreams#",
   "id":"https://example.org/user/123/my-second-follow",
   "type":"Follow",
   "actor":"https://example.org/service/123",
   "object":"http://w3id.org/class/hochschulkompass/S79#"
}

Subscriber is added to as:followers collection of concept:

{
   "@context":{
      "@vocab": "http://www.w3.org/ns/activitystreams#",
      "skos":"http://www.w3.org/2004/02/skos/core#"
    },
   "id":"http://w3id.org/class/hochschulkompass/S79#",
   "name":"Informationstechnik",
   "skos:prefLabel":"Informationstechnik",
   "type":[
      "skos:Concept",
      "Service"
   ],
   "skos:broader": "http://w3id.org/class/hochschulkompass/B74#",
   "skos:inScheme": "http://w3id.org/class/hochschulkompass/scheme#",
   "inbox":"https://skohub.io/inbox?subject=http://w3id.org/class/hochschulkompass/S79#",
   "outbox":"https://skohub.io/outbox?subject=http://w3id.org/class/hochschulkompass/S79#",
   "followers": {
     "summary":"Followers of \"Informationstechnik\"",
      "type":"Collection",
      "totalItems":1,
      "items":[
        "https://example.org/service/123"

      ]
   }
}

Note: It probably makes sense to have a separate URL for the followers collection, e.g. "followers": "https://skohub.io/followers?subject=http://w3id.org/class/hochschulkompass/S79#". Mastodon does it similarly, see e.g. https://openbiblio.social/@acka47.json.

Notification about new resource sent to the subject

{
   "@context":"https://www.w3.org/ns/activitystreams",
   "id":"https://example.org/activity/publish/123",
   "summary":"Teacher A announces a new learning resource for Informationstechnik",
   "type":"Create",
   "actor":{
      "type":"Person",
      "id":"http://example.org/user/124",
      "name":"Teacher A"
   },
   "object":{
      "id":"https://example.org/publish/123",
      "type":"Document",
      "published":"2019-09-22T20:26:05Z",
      "url":"https://example.org/publish/123.html",
      "attributedTo":"http://example.org/user/124",
      "to":[
         "http://w3id.org/class/hochschulkompass/S79#"
      ],
      "sensitive":false,
      "content":"<p>A HTMl representation of the description for the resource</p>",
      "attachment":[
         {
            "type":"PropertyValue",
            "name":"type",
            "value":"CreativeWork"
         },
         {
            "type":"PropertyValue",
            "name":"id",
            "value":"https://example.org/oer/123"
         },
         {
            "type":"PropertyValue",
            "name":"creator",
            "value":"http://example.org/whoever"
         },
         {
            "type":"PropertyValue",
            "name":"title",
            "value":"OER with topic Informationstechnik"
         },
         {
            "type":"PropertyValue",
            "name":"dateCreated",
            "value":"2019-03-01"
         },
         {
            "type":"PropertyValue",
            "name":"datePublished",
            "value":"2019-07-01"
         },
         {
            "type":"PropertyValue",
            "name":"about",
            "value":"http://w3id.org/class/hochschulkompass/S79#"
         },
         {
            "type":"PropertyValue",
            "name":"about",
            "value":"http://d-nb.info/gnd/4430243-5"
         }
      ],
      "tag":[
         {
            "type":"Mention",
            "href":"http://w3id.org/class/hochschulkompass/S79#",
            "name":"Informationstechnik"
         }
      ]
   }
}

As you can see, in this example the actual metadata of the resource is transported in the as:attachment array. There might be a bettr way to do this, though.

Non-ActivityPub- but LDN-compliant version

This approach would make it simpler as we could just open the inbox for resource metadata to be dropped there, e.g. just:

{
    "type": "CreativeWork",
    "id": "https://example.org/oer/123",
    "creator": "http://example.org/whoever",
    "title": "OER in topic Informationstechnik",
    "dateCreated": "2019-03-01",
    "datePublished": "2019-07-01",
    "about": [
      "http://w3id.org/class/hochschulkompass/S79#",
      "http://d-nb.info/gnd/4430243-5"
     ]
}

Announcing publication to followers

The Announce action is characterized like this in the spec:

The Announce activity is effectively what is known as "sharing", "reposting", or "boosting" in other social networks.

{
   "id":"https://skohub.io/outbox/123?subject=http://w3id.org/class/hochschulkompass/S79#",
   "type":"Announce",
   "actor":"http://w3id.org/class/hochschulkompass/S79#",
   "published":"2019-09-22T20:26:55Z",
   "to":[
      "https://skohub.io/followers?subject=http://w3id.org/class/hochschulkompass/S79#"
   ],
   "cc":[
      "https://www.w3.org/ns/activitystreams#Public"
   ],
   "object":"https://example.org/activity/publish/123"
}