FEP-e232: Object Links

Oooh ooh, so firstly, this is great. Second – I have two things that might be of interest.

One is - so, Web Annotations standardized how to link to general text in a paragraph, back in the day. And ‘atjson’ improved upon that mechanism, which then turned into Peritext: A CRDT for Rich-Text Collaboration So, definitely worth glancing at, in terms of prior art (specifically for linking to arbitrary text).

The second item is from the VerifiableCredentials world, which adds cryptographic binding to linking of general objects - Proposal: digestMultibase - Chaining VCs via links and digests · Issue #952 · w3c/vc-data-model · GitHub
In case hash-linking/binding is useful for this FEP.

3 Likes

@silverpill re mediaType again – proposing a change

mediaType (REQUIRED): the media type MUST be application/ld+json; profile="https://www.w3.org/ns/activitystreams". This specification only deals with ActivityPub objects but in practice the media type can be different and servers MAY accept object links which do not comply with the requirement. For example, a media type of application/activity+json SHOULD be treated as equivalent.

motivation: Activity Streams 2.0

Note that while the Activity Streams 2.0 format uses JSON-LD conventions, there are a number of constraints and additional requirements for Activity Streams 2.0 implementations that justify the use of a specific media type. Because Activity Streams 2.0 can be considered a restricted profile of JSON-LD, Implementations SHOULD consider the application/ld+json; profile="https://www.w3.org/ns/activitystreams" media type as being equivalent to application/activity+json.

and also in converse: ActivityPub

Servers SHOULD interpret a Content-Type or Accept header of application/activity+json as equivalent to application/ld+json; profile="https://www.w3.org/ns/activitystreams" for server-to-server interactions.

also if there are no other comments or changes then you can probably request this be finalized?

I agree. Here’s the change #52 - FEP-e232: Add note about application/activity+json media type - fep - Codeberg.org

Pleroma compatibility remains a blocker. I’ll try find some time to submit a pull request to Pleroma and maybe also create an issue in Akkoma bug tracker. If they reject/ignore that, we should consider using attachment property instead of tag.

What’s the issue with Pleroma, and how would using attachment be any better?

EDIT: If it’s as above and Pleroma panics on Link in tag, then Pleroma should not panic. Just filter the tag array for understood types.

Yes, the issue is panic on an unexpected link tag. I’m not a Pleroma maintainer, so the best I can do is submit a patch.
Otherwise the significant portion of recipients will not be able to see notes with FEP-e232 object links.

Some updates:

  • Misskey FEP-e232 pull request was closed.
  • I submitted a pull request that fixes tag validation in Pleroma but it hasn’t been accepted. It seems that proper fix would require major refactoring and I don’t have the ability to do that.
  • Mastodon developers are considering implementation of quote posts. The 6 years old issue has been reopened.
2 Likes

FoundKey implemented object links for detecting quotes : #318 - server: implement FEP-e232 style quotes - FoundKey - Akkoma Development

The code filters the tag array for:

  • is a link (has an href)
  • with a mediaType of one of the activitystreams types ( application/ld+json; profile="https://www.w3.org/ns/activitystreams", application/activity+json)
  • where the rel is any of the three URIs of legacy “quote” properties ( https://misskey-hub.net/ns#_misskey_quote, http://fedibird.com/ns#quoteUri, https://www.w3.org/ns/activitystreams#quoteUrl)

It does not currently detect object links in any other context, however.

2 Likes

There are things left unaddressed in this proposal:

  1. If I want to quote/cite/link to wikipedia, I would want to use an Object Link with mediaType “text/html”. I am well aware that this extends the scope of the proposal, which is only for links to ActivityPub objects. However, this extension feels natural to me and doesn’t seem to cause any problems.

  2. I would like there to be a attributedTo field in the Link, see below. The actor in attributedTo should then be handled similarly to a mention, i.e. be included in the to recipients.

        {
            "type": "Link",
            "mediaType": "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"",
            "href": "https://example.com/objects/123",
            "attributedTo": "https://example.com/users/johnfep",
            "name": "RE: https://example.com/objects/123"
        }
  1. I feel the idea of name being abused as a “replace in HTML” is horrible. The content field should already contain the formatted content. Writing a FEP to support “lipstick on a pig” behavior of Apps seems counter productive to get a good standard.
    However, I’m the first to admit, that I’m unsure what a better solution would be.

by definition this is not an Object Link, it is just a Link. an “object link” refers specifically to a Link where the target is an ActivityPub Object

Link is already defined in ActivityStreams and doesn’t need its own extension. you can already use a Link wherever you feel appropriate; what is specifically useful, however, is knowing when such a link refers to something “on the network” versus “off the network”, which is why this FEP exists

Link does not define attributedTo, as that is a property of objects and not links. the example you provided appears to be an object link already, which means you can fetch or dereference the object (https://example.com/objects/123) and use attributedTo from there.

it might not! content might be text/plain instead of text/html. the purpose of name is to define microsyntaxes such as @mention and #hashtag as qualified links to some other web resource. in other words, you take the plain text string @mention and mark it up as a Link to (or perhaps more specifically a Mention of) the actor located at href

yes, there is some complexity in extracting which <a> tag is associated with which Link in tag, but is not insurmountable and not what i’d call “lipstick on a pig” either. you can work backwards by taking the innerHTML of each anchor, strip all HTML from it, and compare if that resulting plaintext matches the name. i’d suggest comparing href to href but unfortunately some implementations use a different href in content than in tags – i think mastodon in particular links to id in the tag Link href, but to the url in the content <a> tag. the important thing is that tag name operates on plaintext even if the content is in html.

for more on microsyntaxes see Activity Vocabulary

3 Likes

Why not add a separate tag with type Mention? I think there should be a clear separation of concerns between object links and actor links (aka mentions).

Whats the current timeline of this FEP getting finalized?

Some context about the mentioned Misskey pull request: That was also authored by me, however the primary maintainer did not seem to be too interested in it and just ignored it completely (this happened a few times with other things too, one of the reasons for forking). Since I forked, they significantly restructured their code base so I was unable to update that pull request. It formed the base for Foundkeys implementation instead.

FEP-e232 is still incompatible with Pleroma, but we’re making progress: TagValidator: Drop unrecognized Tag types (!3823) · Merge requests · Pleroma / pleroma · GitLab. Pleroma forks (Akkoma, Rebased) don’t have this problem.

I’m confident that this proposal will not change in any significant way, but I would like to resolve the Pleroma compatibility issue before finalizing.

@Johann150 I’m looking at extractQuoteUrl function in FoundKey and it seems that you only accept certain rels: FoundKey/tag.ts at main - FoundKey - Akkoma Development

I’m curious, what’s the reasoning behind this? What relation type would you recommend? My implementation leaves rel property empty at the moment, because it works with object links like they are generic “object mentions”, rather than quotes.

i’m not johann but i would guess that foundkey draws a distinction between simply linking to an object vs. it being a “quote” as understood by misskey, fedibird, etc. – in effect, the definition of the _misskey_quote link relation is that the referenced resource (href) is being quoted by the current resource, according to misskey’s understanding of a quote. consider the following:

{
  "id": "https://example.com/some-object"
  "content": "<p>I made <a href='https://example.com/post-1'>this post</a> and <a href='https://example.com/post-2'>this other post</a> some time ago. I also made <a href='https://blog.example.com/static'>this external post</a> on my static site.</p><p><a href='https://example.com/quoted-post' rel='_misskey_quote'>RE: https://example.com/quoted-post</a></p>",
  "tag": [
    {
      "type": "Link",
      "name": "this post",
      "href": "https://example.com/post-1",
      "mediaType": "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\""
    },
    {
      "type": "Link",
      "name": "this other post",
      "href": "https://example.com/post-2",
      "mediaType": "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\""
    },
    {
      "type": "Link",
      "name": "this external post",
      "href": "https://blog.example.com/static"
    },
    {
      "type": "Link",
      "name": "RE: https://example.com/quoted-post",
      "href": "https://example.com/quoted-post",
      "mediaType": "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"",
      "rel": ["_misskey_quote"]
    }
  ]
}

(too lazy to type out the full uri for _misskey_quote so forgive me for that)

you can see from the above example that there are 4 links, 3 of which are object links, and only 1 of which is a misskey quote. a consuming application might embed the misskey quote as a preview, but not embed the other two object links. but it would probably want to load those two object links natively instead of in an external browser/tab as HTML.

(aside: if you want to deal with “object mentions” then i would consider use of Mention for that. a Mention is still a Link, just one that is intended to notify? or if not that, then one that is intended to refer to an actor. it’s never explicitly stated what a “mention” is supposed to be, and the examples in as2 pretty much relegated themselves to only covering the @mention microsyntax with no additional semantics clearly described.)

1 Like

What trwnh says is correct: I think that the act of deciding whether something should be shown as a previewed thing should be deliberate. (The other use of link is also a good idea but not something I have implemented yet.)

There is also a bit more of a distinction. This FEP defines links to any ActivityPub Object or Actvitity, but the semantics of the three rels you mention [1] are (apart from the deliberate distinction I mentioned above) that they link specifically to something Foundkey considers to be “post” [2]. This is because the database schema as well as the frontend can only handle quotes of “posts”.

The choice of these rels is because the terms which were used to represent this had these URIs in the JSON-LD context so I thought it appropriate to use them instead of coming up with something new. And please don’t come after me for quoteUrl which is of course not actually part of AS, but has been “grandfathered” from previous use. If you want something to show up as a “quote” on Foundkey, you can use any of these three rels, there is no difference between them so I wouldn’t make a recommendation to use one or the other.

[1] https://misskey-hub.net/ns#_misskey_quote, http://fedibird.com/ns#quoteUri and https://www.w3.org/ns/activitystreams#quoteUrl
[2] currently, an Object of type Note, Question, Article, Audio, Document, Image, Page, Video or Event

2 Likes

Thanks for explanation. I think I will add relation type to the first object link in a post, and leave other links without rel attribute (if there is more than one link). Still not sure which value to use. Misskey have had quotes since 2018, but were they the first ActivityPub project to implement quotes?

cc @macgirvin (I noticed that you implemented FEP-e232 in Streams, and you also don’t add rel attribute)

We’ve had quoted posts in the fediverse since at least 2010. Possibly earlier. We’ve always treated them just like including an article from CNN or blogger- we generate a snippet or “card” from any metadata present at the given URL and put it on the page as HTML and send it. We also generally provide an attachment because that’s the way this works in MIME and OStatus as we’re providing a link to content that is already present in the activity. We also provide a tag ala FEP-e232 for use by projects that incorrectly assume this is merely a “reference”.

cc @macgirvin (I noticed that you implemented FEP-e232 in Streams, and you also don’t add rel attribute)

As I recall this didn’t work well with our use case and it does say that rel is “optional”. Did I miss an update that made it mandatory? It is not reflected in the post at the top of this page.

rel should still be optional, yes. the purpose of rel in Foundkey is to identify which object links are specifically misskey-style “quote posts”, as opposed to simply linking to a post. in other words, the purpose of mediaType is to hint that the Link can be opened in-app, and the purpose of rel is to provide semantic purpose (“this is a misskey-style quote”)

given that not every single implementation shares the same concept of a “quote”, there are naturally multiple different ways to do “quoted posts”.

  • tag is loosely for tagging stuff in content or otherwise referenced.
  • attachment is loosely for attaching stuff as a sidecar next to content or otherwise included or considered part of the post.
  • inReplyTo could even be considered a form of “quote” if you just embed a preview of the replied-to post

functionally, each of these approaches does something slightly differently, depending on whether you want to have the link in the content or not, and whether it is semantically a “reply” or not.

1 Like

It’s not mandatory per FEP-e232, but I think it’s reasonable to expect that some implementations may ignore object links that are not explicitly marked as quotes.

I will probably use rel: https://misskey-hub.net/ns#_misskey_quote for that purpose, but my implementation will continue to accept any object link where link target looks like a post, with rel or without.

In our case it’s fine if they ignore it, because the included content is already present in the activity content field. We don’t actually need it. It’s just a hint to those platforms which aggressively filter HTML; although these are typically the same platforms that reject quoted posts, so they’re probably going to reject it anyway.