FEP-07d7: A Custom URL Scheme and Web-Based Protocol Handlers for Linking to ActivityPub Resources

I just re-read the web+ap proposal. I remember it seeming more complicated the first time I saw it. Maybe because it’s kind of under spec’d and I was reading more into it than is actually there. I’d really like to harmonize the two proposals.

You’re right that the protocol handler itself is on the order of 20 lines of javascript, assuming that the app can already resolve and display arbitrary AP objects. There’s just several chicken and egg problems happening simultaneously. There’s two ways this stuff can go: apps implement ahead of the standard, or the standard gives apps a target to implement toward. So far apps haven’t taken the lead, so here we are trying to get the standard to do so.

3 Likes

I’ve thought about this quite a few times since the Web Intents days, and I always thought it might not be the best idea to name the handler after a specific protocol like ‘activitypub’ vs the context/intent of things so I imagined something more like web+social rather than web+activitypub. naming is hard but my 2c

(may even be better to just be like verb/intent-specific like web+post and then there can be different protocol handlers for each intent)

1 Like

Honestly, that’s exactly the kind of fragmentation I wanted to avoid. There’s no universal “follow” or “reblog” or “create” independent of the protocol and applications that implement it. The scheme describes the resource. How to retrieve and parse it. Not the action to take upon the resource. That’s why we have schemes like http: and ftp:, and not document:

4 Likes

Fair enough. I think I understand your intent more.

I like how a lot of times on the web, it is encouraged for the web document author to leave the specifics up to the end-user by way of how they configure their user-agent. Then the user + user-agent can decide what protocol makes sense, not the author of the web document. Subtle distinction but powerful.

There’s no universal “follow” or “reblog” or “create” independent of the protocol and applications that implement it.

WebIntents is a protocol for that. Web Intents
I think I just wanted to highlight that ActivityPub doesn’t have to be the protocol for that, it can be an option for end-users to decide to use based on their user-agent.

But I hear you don’t want to fragment/interop across anything other than activitypub so no need to use this. Like I said, ‘my 2c’

1 Like

I feel like not registering a handler because an application might not handle every conceivable option means in the future as more and more use-cases are implemented using ActivityPub, no one will practically handle everything well and then we wouldn’t have handlers.

I think it’d be fine to register the Peertube client. Then depending on how much work the client dev wants to do, they could detect what kind of object it is, and if they don’t handle it, tell the user, for example, “This is a text post but Peertube is a video platform. Click one of the options below that is compatible with this object.” Which would include, if available, a link to view it on the original instance’s provided UI.

It would be cool if clients could register only for links they can open, but I can’t think of a way to feasibly do it.

I have realized what this FEP needs: A logo.

Justification: I’ve been building a home timeline for myself. It would be nice to offer a FEP-07d7 button similar to the open original page one. For this, I need a logo!

Over all, I think that if the protocol handler had a recognizable logo, people might start using it. Think about the RSS logo, you look for on a website to find the readable version.

I imagined we would just use the ActivityPub logo. I tried to suggest that with the “AP” button in the very quick UI mockup I shared in this post, but maybe that doesn’t read.

It now looks like this. Hope this matches your intentions.

1 Like

hello! (finally managed to get the confirmation email to go through.)

so the issue we have with this FEP (and why fedilinks isn’t a FEP - aside from we weren’t able to confirm our email before) is because there’s no point to an URI scheme without the fallback behavior. this fallback behavior (formally “browsing behavior of web+ links”) goes beyond fedi, so it’s not really appropriate for a FEP, as those are inherently fedi-specific.

our experience deploying fedicraft during blanketcon 2023 was that restricting the links to instances that have the fallback handler is a net negative, so this time we’re deploying fedicraft during modfest 1.20 without that restriction. web+ap being implemented in tokodon and feditext means users can actually use it today, even if the target instance doesn’t support the fallback.

what happens when you click it and you don’t have tokodon or feditext installed? you get shown an error page, a 404. we believe exposing this 404 to users can actually help promote fedilinks adoption, while with this FEP you get… nothing. clicking a link of this FEP without a client installed just does absolutely nothing. there’s nothing server admins can do about it, and the user is required to use an app to see it (likely a native app too, due to registerProtocolHandler support in browsers today being rather poor, basically throwing out the possibility of instance support entirely).

we note that our approach does rely on native apps like IRC clients and minecraft mods to adopt it first, then browsers and OSes. we figured this was a good tradeoff because good luck convincing browser/OS devs that your thing doesn’t have a privacy impact. (btw: it doesn’t. either the server knows you used the fallback (which is fine, especially if it were widely adopted), or it knows absolutely nothing, with your app of choice intercepting the URI. some other folks suggested an approach where the OS fetches the URI and checks for Link headers but that would be terrible from a privacy perspective, as it would e.g. bypass your activitypub client’s proxy settings.)

1 Like

I just don’t agree that a fallback handler is necessary, or even useful. If I try to follow a mailto:// link without a handler, the last thing I want is for the app I’m in to try to load something from the email address’s domain. I want it to do nothing, or at most, ask to search for an appropriate handler. This has been standard behavior for these things for at least 30 years.

And I also don’t agree that registerProtocolHandler is inadequate for this task. It’s the web. We have regular links. You can and should put the regular link to the origin server’s web view next to the web+activitypub link. And you can and should style the web+activitypub link unlike other links to make it clear it will be handled in a user-defined way, rather than a browser-defined way.

And, as you correctly point out, browser and OS behavior is out of scope for a FEP. This proposal works with the tools we have. Those tools could be improved, but I personally think fedi developers will have more success in advocating for those improvements by becoming meaningful stakeholders.

1 Like

Pretty much. I imagined more of a button, probably with text, than just the logo image by itself. But the clearest UI patterns probably need to be found through trial and error.

1 Like

hm. right.

so. we believe we need web+ap links to replace https links for fediverse posts and accounts if we want users to share web+ap links instead of https links.

the social aspects of this, the sharing of these web+ap links, is fundamental to whether or not we can succeed. because what’s the point of supporting something nobody but a few can use? and how do you convince every website with a text box to check if an https link is fediverse and then insert an web+ap link alongside it if it is? not even most fedi instances check if links are fedi before linking them.

You don’t. If people are just emailing links to each other (for example), those are going to be regular links that they copy out of the address bar. I expect that will always be true.

The origin app itself should embed the custom scheme links in the web view. That way it becomes a 1-click action to re-open the relevant object from the user’s app or server of choice. This is the same basic idea as Mastodon’s “Take me home” feature, except it doesn’t require any typing, isn’t specific to mastodon, and works on any activitypub object rather than just actors.
image

Over time, with widespread adoption, it would make sense for client apps to help craft and provide these links for sharing. But only over time. This FEP is intended to be beneficial at every point throughout an extended period of uneven adoption.

Can we assume the choice to deviate from RFC 3986’s “generic URI syntax” was deliberate and intended to avoid fedilinks compatibility?

Uh, no, that is me not having an encyclopedic knowledge of web RFCs, mostly. I don’t have strong opinions on the scheme prefix. I chose web+activitypub because it seemed to come up a lot in discussions of similar proposals in the past.

We don’t mean the scheme we mean the syntax.

web+activitypub:https://... is not generic syntax, while web+ap://... is.

This is also relevant for all the software that parses RFC 3986 URIs out there, like Java, Qt, among others…

1 Like

I’ve also now build a solution to register the necessary protocol handlers for opening stuff in Mastodon:

https://fep-07d7.bovine.social/

Note: A request is made against the Mastodon API to determine the URL to open.

2 Likes

Another benefit of fedilinks we forgot to mention (sorry):

Whenever an instance ends up implementing the fallback handler (for example to better accommodate ModFest participants), assuming the instance has a built-in webclient (e.g. mastodon, misskey, NOT GoToSocial), well that’s also a regular protocol handler (by design). you can just use that, you don’t have to fiddle around with hacks and workarounds. it just works!

1 Like

FYI I updated the FEP based on the discussion so far. The main thing is to prohibit embedding https:// in the web+activitypub: uri, because it contradicted RFC-3986. I also updated the examples, accordingly. And I tightened up the safety-related recommendations for handling user-provided URIs.

Thanks for the feedback

Link to the diff

1 Like

that’s not quite right either… the // is important, it’s what defines the “authority” (hostname and optional port), otherwise an RFC 3986 parser would parse it as a path. we would encourage playing with a real RFC 3986 parser like URI — Elixir v1.12.3 to get a feel for it. consider:

iex(4)> URI.parse("web+ap://chaos.social/@SoniEx2")
%URI{
  scheme: "web+ap",
  authority: "chaos.social",
  userinfo: nil,
  host: "chaos.social",
  port: nil,
  path: "/@SoniEx2",
  query: nil,
  fragment: nil
}
iex(5)> URI.parse("web+activitypub:chaos.social/@SoniEx2")
%URI{
  scheme: "web+activitypub",
  userinfo: nil,
  host: nil,
  port: nil,
  path: "chaos.social/@SoniEx2",
  query: nil,
  fragment: nil
}

meanwhile, tuba joined in on implementing web+ap! so we’re up to 3 fedilinks-friendly clients now. :3

1 Like