Bookmarks

I’d like to share and receive bookmarks, but the spec has some room for interpretation as to how a bookmark can be represented. This is what I have so far:

  • User actors have a collection called bookmarks
  • When a user wants to bookmark something, a Add{Document} activity is generated:
{
  "@context": "https://www.w3.org/ns/activitystreams",
  "type": "Add",
  "actor": "https://tavern.town/users/nick",
  "object": {
    "id": "https://tavern.town/objects/8dc00625-474e-405e-94e7-e9b17551e749",
    "type": "Document",
    "name": "Tavern Town",
    "url": "https://tavern.town/"
  },
  "target": "https://tavern.town/users/nick/bookmarks"
}

I’m avoiding using the Link type because the spec implies that Links are used to create relationships between objects and target contents:

When a Link is used, it establishes a qualified relation connecting the subject (the containing object) to the resource identified by the href.

This makes sense to me as mentions and hashtags are types of Links specifically used to associate content, actors or collections, with objects like Notes.

Another alternative would be to use the existing schema.org taxonomy as described on https://schema.org/WebSite. I’m hesitant to go in this direction though.

{
  "@context": {
    "as": "https://www.w3.org/ns/activitystreams",
    "schema": "http://schema.org"
  },
  "@id": "https://tavern.town/activities/02e029d6-e647-4ef3-b539-bb96a8f69030",
  "@type": "as:Add",
  "as:actor": "https://tavern.town/users/nick",
  "as:object": {
    "@id": "https://tavern.town/objects/8dc00625-474e-405e-94e7-e9b17551e749",
    "@type": "schema:WebSite",
    "schema:url": "https://tavern.town/"
  },
  "as:target": "https://tavern.town/users/nick/bookmarks"
}

I was a developer on the del.icio.us team years ago and have some opinions, but I’d like to get feedback.

1 Like

Hi Nick,

I understand a bookmark as the qualified relation between the person who makes the bookmark (represented by the actor) and the Document that is pointed at. So I would represent bookmarks as a collection of Links, where each bookmark has a Document object.

You mention Document in your example. I guess you chose this over Article because of url. So why not a collection of links?

For me a Bookmark is to a Page what a Mention is to a Person.

Does it make sense? Would you expand on why would prefer not to use Link in this case? I mean, I could annotate a bookmark or tag it so I can search its kind later on, not unlike what you seem to be describing.

FWIW, Prismo uses Article or Page, using an absence of URL as a marker for local resources, while Lemmy uses Page – both are Reddit-like link aggregators.

I used to be a heavy del.icio.us user. :slight_smile:

Continuing with the above example, the bookmarks collection would look like this:

{
  "@context": {
    "as": "https://www.w3.org/ns/activitystreams"
  },
  "@id": "https://tavern.town/users/nick/bookmarks?page=1",
  "@type": "as:OrderedCollectionPage",
  "as:orderedItems": [
    {
      "@id": "https://tavern.town/objects/8dc00625-474e-405e-94e7-e9b17551e749",
      "@type": "as:Document",
      "as:name": "Tavern Town",
      "as:tag": [
        {
          "@type": "as:Hashtag",
          "as:name": "#activitypub"
        },
        {
          "@type": "as:Hashtag",
          "as:name": "#tavern"
        }
      ],
      "as:url": "https://tavern.town/"
    },
    {
      "@id": "https://tavern.town/objects/7b2f4d66-df08-4d24-abfd-ef9590d0492c",
      "@type": "as:Document",
      "as:name": "Tavern on GitLab",
      "as:tag": [
        {
          "@type": "as:Hashtag",
          "as:name": "#gitlab"
        },
        {
          "@type": "as:Hashtag",
          "as:name": "#tavern"
        }
      ],
      "as:url": "https://gitlab.com/ngerakines/tavern/"
    }
  ],
  "as:partOf": "https://tavern.town/users/nick/bookmarks",
  "as:totalItems": 2
}

Yeah, that makes sense. From what I read on https://www.w3.org/TR/activitystreams-vocabulary/#dfn-link, the Link type is used to create explicit relationships between things. Take, for example, the Mention or Hashtag types. When used within an object, they create an explicit attachment between the object and the tag or actor that they reference. I’m hesitant to use the Link type now, because I read them as supplemental types to enhance existing types. Although they could be used on their own, I’d be worried about how activities that reference them would be modified by them, vs having them as the object of the activity.

Thanks, that is good to know. On delicious, the href content is considered an arbitrary payload. There was some parsing that was done for de-duplication, but you can stuff anything inside of it. My first thought was to go with Document, because all of these are valid bookmarks in my opinion:

I think a Document is better suited to represent the different kinds and is closer to “some thing with a URL” than Page or Article. Going with Document (or anything that extends Object) allows for additional meta-data vs having a flat list of URLs in the collection as well.

Hi @ngerakines
Do you expect that Bookmarks can be not only added or removed, but updated also (e.g. to change a list of tags or name)?
I think that doing such updates via Remove + Add would be inconvenient…

Yeah, bookmarks can be created (added to the bookmarks collection), deleted (removed from the bookmarks collection), or updated. Given that each bookmark Document has a unique identifier in this example, I don’t think that performing an Add{Bookmark}~Collection[Bookmarks] or Remove{Bookmark}~Collection[Bookmarks] is necessary each time the bookmark is updated.

In this implementation example, each user actor would have a single bookmarks collection that the bookmark Document objects are added to. Additional activities could be published (Create{Document}, Update{Document}, etc.).

Good. For a long time I (and other people with whom I discuss this) are dreaming of having a way to tag/bookmark Notes / Activities privately, and not only “Like” or “Announce” them.
Being able to have such bookmarks at a server side allows to sync them between all client devices…

Actually such “bookmarks” can be used even to mute Actors…