Skip to content

ActivityPub based SkoHub

Adrian edited this page Jul 10, 2019 · 18 revisions

This wiki page reflects on the details of implementing #16 Switch to ActivityPub for subscriptions.

I start with the things we will definitely need:

  1. inbox and outbox for subjects
  2. Users/clients being as:Agents
  3. Follow requests by clients and maintaining a followers collection

Afterwards I will discuss different options for notifying a subject about a new resource that is about it.

Inbox & Outbox for subjects

JSON-LD

{
   "@context":{
      "@vocab": "http://www.w3.org/ns/activitystreams#",
      "broader":"http://www.w3.org/2004/02/skos/core#broader",
      "Concept":"http://www.w3.org/2004/02/skos/core#Concept",
      "ConceptScheme":"http://www.w3.org/2004/02/skos/core#ConceptScheme",
      "hasTopConcept":{
         "@id":"http://www.w3.org/2004/02/skos/core#hasTopConcept",
         "@container":"@set"
      },
      "inScheme":"http://www.w3.org/2004/02/skos/core#inScheme",
      "narrower":{
        "@id":"http://www.w3.org/2004/02/skos/core#narrower",
        "@container":"@set"
      },
      "notation":{
        "@id":"http://www.w3.org/2004/02/skos/core#notation",
        "@container":"@set"
      }
    },
   "id":"http://w3id.org/class/hochschulkompass/S79#",
   "prefLabel":"Informationstechnik",
   "type":[
      "Concept",
      "Object"
   ],
   "broader": "http://w3id.org/class/hochschulkompass/B74#",
   "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":0,
      "items":[
      ]
   }
}

Note, that the use of subject is temporary as parameter to indicate the concept or element of a KOS the inbox/outbox belongs to. There are probably better name choices.

Optional: HTTP Header

As is alread yimplemented: Link: <https://skohub.io/inbox?subject=http://w3id.org/class/hochschulkompass/S79#>; rel=http://www.w3.org/ns/ldp#inbox

Users/clients as as:Agent

N.B. To be clear, users/subscribers shouldn't be managed by SkoHub but by external applications.

Service

Both as:Service and as:Application exist. In this example I am using as:Service 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"
}

User

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

Subscription: User/service makes follow request

{
	"@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#"
}

Subscription: SkoHub adds subscriber to followers collection

{
   "@context":{
      "@vocab": "http://www.w3.org/ns/activitystreams#",
      "broader":"http://www.w3.org/2004/02/skos/core#broader",
      "Concept":"http://www.w3.org/2004/02/skos/core#Concept",
      "ConceptScheme":"http://www.w3.org/2004/02/skos/core#ConceptScheme",
      "hasTopConcept":{
         "@id":"http://www.w3.org/2004/02/skos/core#hasTopConcept",
         "@container":"@set"
      },
      "inScheme":"http://www.w3.org/2004/02/skos/core#inScheme",
      "narrower":{
        "@id":"http://www.w3.org/2004/02/skos/core#narrower",
        "@container":"@set"
      },
      "notation":{
        "@id":"http://www.w3.org/2004/02/skos/core#notation",
        "@container":"@set"
      }
    },
   "id":"http://w3id.org/class/hochschulkompass/S79#",
   "prefLabel":"Informationstechnik",
   "type":[
      "Concept",
      "Object"
   ],
   "broader": "http://w3id.org/class/hochschulkompass/B74#",
   "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#"

Forwarding notification to followers

The Announce action probably makes sense here, being characterized like this in the spec:

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

{
  "@context": "https://www.w3.org/ns/activitystreams",
  "summary": "Teacher A announces a new learning resource for Informationstechnik",
  "type": "Announce",
  "actor": {
    "type": "Person",
    "id": "http://example.org/user/124",
    "name": "Teacher A"
  },
  "to": [ "https://example.org/service/123" ],
  "object": {
    "@context": "https://www.w3.org/ns/activitystreams",
    "id": "https://example.org/announce/123",
    "summary": "Teacher A announces a new learning resource for Informationstechnik",
    "type": "Add",
    "actor": {
      "type": "Person",
      "id": "http://example.org/user/124",
      "name": "Teacher A"
    },
    "target": "https://skohub.io/inbox?subject=http://w3id.org/class/hochschulkompass/S79#",
    "object": {
      "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"
       ]
    }
  }
}

Sending notifications to an Inbox

One question to decide is how we want people to send notifications about new resources to the inbox. Should this process be ActivityPub-compliant or not? If yes, how should it be implemented?

ActivityPub-compliant notifications

If meassage to a subject's inbox need to be comply with the ActivityPub specification, the question arises which activity to use for this: Add, Create or maybe Announce?

From the wording, Announce seems the best to use:

Indicates that the actor is calling the target's attention the object.

Howeverm as Announce also is charaterized as "sharing" or "boosting" it sounds more like a it applies to an as:Object being shared. But we just want to share a web resource in general via its metadata.

Notification about new resource sent to the subject

The example is using Add but I am not sure that this is intended use.

{
  "@context": "https://www.w3.org/ns/activitystreams",
  "id": "https://example.org/announce/123",
  "summary": "Teacher A announces a new learning resource for Informationstechnik",
  "type": "Add",
  "actor": {
    "type": "Person",
    "id": "http://example.org/user/124",
    "name": "Teacher A"
  },
  "target": "https://skohub.io/inbox?subject=http://w3id.org/class/hochschulkompass/S79#",
  "object": {
    "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"
     ]
  }
}

Non-ActivityPub- but LDN-compliant version

This approach would make it simpler.

Clone this wiki locally