Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

URL scheme for remote follow, share buttons #2291

Closed
kornelski opened this issue Apr 21, 2017 · 24 comments
Closed

URL scheme for remote follow, share buttons #2291

kornelski opened this issue Apr 21, 2017 · 24 comments
Labels
api REST API, Streaming API, Web Push API

Comments

@kornelski
Copy link

kornelski commented Apr 21, 2017

Decentralized nature of Mastodon causes rather awkward flow for the "Remote Follow" operation. Similarly, there's no way to make an easy "Share" button.

The root of the problem is that websites don't know which Mastodon instance they should use to perform the operations for their visitors.

I think this problem can be solved quite well with custom URL schemes. It's possible to register a website (a Mastodon instance) to handle links with a custom URL scheme (registerProtocolHandler). This registration is per user/per browser, so it's compatible with the decentralized system and doesn't rely on any central infrastructure.

There could be a URL scheme for Mastodon commands, such as "follow" or "toot". Users could allow their preferred instance or app to handle this URL scheme. Even users who use multiple instances could assign the URL scheme to a "chooser" app that lets them redirect the request to any of their instances.

The URL could be something like this:

web+toot:follow/@handle@instance

and then the Remote Follow button could be something like this:

<a href="web+toot:follow/@handle@instance">Remote Follow</a>

(actually bit more complex to have an HTTP URL fallback, and act more like button, especially in screen readers, but you get the idea)

This way a click on the URL could instantly redirect user to their preferred instance, without asking for the handle and the instance. Similarly, URLs like web+toot:share?text=Hello could be used to implement "Share" buttons that work as seamlessly as on centralized social networks.

@wxcafe wxcafe added api REST API, Streaming API, Web Push API enhancement labels Apr 21, 2017
@Gargron
Copy link
Member

Gargron commented Apr 21, 2017

I'm gonna read up on this protocolHandler, it sounds like it could work, indeed.

@RexOrCine
Copy link

I think we're going to strip down what social buttons we display on our website. If we have a Mastodon button on our landing page (or on articles etc throughout the site) and someone who doesn't have a Mastodon profile clicks on it, it'll need to open up a sign-up prompt of some sort.

@jdmansour
Copy link

jdmansour commented May 29, 2017

Can we use custom protocol handlers to include resources? As in

<script src="web+toot:createLikeButton.js"></script>

That would be pretty nice (edit: and dangerous as I just realize :-D), then other instances could customize themselves when I am logged in or have set up a favorite identity. Saner alternatives would be to try reading JSON from the custom protocol via XMLHttpRequest, or including it in an iframe (that at least I think should work).

For a more general approach in making a default identity known, see my linked issue above (although the more I think about it, the url handler solution is pretty elegant).

@sandhawke
Copy link

I just put together a demo of doing this using protocol handlers. Not in Mastodon, just some web pages that interact in the right way to show this works. It works for me in Firefox and Chromium on Ubuntu, but not Chrome on Android. Not really sure how to debug Chrome on Android.

It does something really nice: it can tell you if you're already following someone, making follow a toggle, instead of a blind click. The same scheme can also be used for 'liking' ordinary static web pages, like the Facebook Like button. It could even be used for showing comments about a page as known by your mastodon instance. That is, it's a general solution to decentralized in-page social interactivity (as in swicg/general#5 )

I used a scheme like: web+inpagesocial:follow?item=http://bar.example

Code is at https://github.com/sandhawke/in-page-social-demo and the readme links to a running demo. Or you can run it (in node.js) on localhost.

I think this works well except (1) maybe not on Android, and (2) the browser UI on adding these handlers is fairly confusing. In Chrome, you'd never notice if the app didn't point it out to you. To make this at all practical for most users, I suspect Mastodon will have to sniff the browser and give very careful, graphic instructions for how to add the handler on that browser.

There's an alternative technique that lets us have a better UI, not under the control of the browser, in exchange for putting a bit of trust (but in an easy-to-verify way) in one domain. But otherwise it's pretty much the same. For it, instead of using protocol handlers, you use nested iframes. So the "away" page loads an iframe from, say, opensocial.org, which has in its localstorage the URL of the "home" site, so it can open another iframe. I implemented this some years ago and it seemed fine. I justify the centralization there by saying it's really just a polyfill until browsers provide the functionality in an acceptable manner. I figure the middle-iframe-server could be run by someone non-commercial and fairly trusted, like W3C (my part-time employer), Apache Foundation, or Internet Archive. User data would never touch their servers; we'd just be trusting them not to turn off the service or serve a malicious iframe.

I can't really gauge how important Facebook's social plugins are to people, but I'd really like to have a decentralized alternative.

@jdmansour
Copy link

This is pretty cool, thanks for putting this together!

It seems it is not (yet?) supported on mobile: https://caniuse.com/#feat=registerprotocolhandler

As to the follow buttons and social plugins, they are not so important to me personally, but I'd really like closer integration between mastodon instances, so they'd feel like one single site. I wonder if in this solution, the remote page can get information out of the iframe, or if it is blocked by single origin policy?

The central server is a kind of polyfill, I think of it like a Gnutella GWebCache. Gnutella was a completely decentralized peer-to-peer file sharing application, but it had the problem of finding initial nodes to connect to. People set up GWebCaches at well-known URLs, which were just simple PHP scripts that helped the nodes find each other. It was a degree of centralization, but it was not a huge problem for the network if one was taken out.

@nightpool
Copy link
Member

nightpool commented Jun 4, 2017

@sandhawke I can't seem to get it to work. It just displays blank iframes, even after allowing the protocol handler

nevermind, I closed everything and tried it again and it worked, as long as I made sure to register the protocol handler before loading the "away" site.

@sandhawke
Copy link

sandhawke commented Jun 4, 2017

Re mobile, oops! I was misled by discussions of protocol handlers on mobile, which I guess were actually about native protocol handlers. So, for example, tusky could register a handler to work inside the iframe, I think. I wonder if it's allowed to register a handler starting with "web+" or we'd need a failover mechanism. I guess in practice we'd usually want the page starting with an ajax call to see if it's working.

As far as closer integration and talking to the iframe, yes, in either the protocol handler approach or the nested iframes approach, the home site page inside the iframe and the away site page can exchange arbitrary information using postMessage. In my thing years ago I used this extensively, for negotiating the size of the window and actually for the away page to have database access to a sandbox database on the home site. For example we could allow the away site to ask to post some messages on the users behalf, or query the user's social graph. Obviously one would need to be extremely careful about such functionality, but the technology shouldn't be a problem.

I think we do want to be careful about privacy, even with the plain follow-button. I believe we need to avoid the possibility of this being used to track people, e.g. by the away site learning the home site's URL without the user's permission. Sure, when the user clicks follow the away page can learn that, but it shouldn't happen just because the follow button is displayed.

@akihikodaki
Copy link
Contributor

The scheme and similar interactive features should be standardized because it could be used with other ActivityPub or OStatus applications.
swicg/general#5 is surely a good place to discuss about the generic direction for the standard. If the scheme is going to be specific for a certain protocol such as ActivityPub, it should have its own site for discussion.

@akihikodaki
Copy link
Contributor

If we have a Mastodon button on our landing page (or on articles etc throughout the site) and someone who doesn't have a Mastodon profile clicks on it, it'll need to open up a sign-up prompt of some sort.

#2291 (comment)

Technically it is difficult to implement the feature with this approach as concerned. The standard has isProtocolHandlerRegistered, but it is not implemented in Firefox and Chromium while WebKit has. Privacy and tracking seems the main concern and it is unlikely to be implemented even in future.
HTML Standard (WHATWG)
https://html.spec.whatwg.org/multipage/system-state.html#dom-navigator-isprotocolhandlerregistered
440620 - Implement navigator.isProtocolHandlerRegistered and navigator.isContentHandlerRegistered (Mozilla)
https://bugzilla.mozilla.org/show_bug.cgi?id=440620
121825 - Implement navigator.isProtocolHandlerRegistered() - chromium - Monorail
https://bugs.chromium.org/p/chromium/issues/detail?id=121825
73176 – Add 'isProtocolHandlerRegistered' and 'unregisterProtocolHandler'. (WebKit)
https://bugs.webkit.org/show_bug.cgi?id=73176

By the way, I am not sure if it is good to have the feature. It sounds like kind of enclosure and exclusive for other Mastodon instances and federated SNSes like GNU Social.
Consider the case Google implemented a fallback for mailto scheme to GMail with isProtocolHandlerRegistered for example. Its user experience would not always be good.

@Gargron
Copy link
Member

Gargron commented Jul 3, 2017

@akihikodaki We only have 3 options, I think:

  1. "Remote follow" button, where you input your username@domain, the button needs to do a webfinger query to get the right URL template for a redirect to authorize the follow. Mind you there is no written standard for this afaik, but we do it the same way as GNU social, and it's pretty reasonable in terms of being software-agnostic
  2. Protocol handler, requires a Mastodon instance to have been visited before, but should be possible to just redirect to the right place instantly without extra user input. Likely to be Mastodon-specific.
  3. Central website that provides embedded JS and stores a global cookie, so it can redirect you to the right place. Likely to be Mastodon-specific

Protocol handlers look the cleanest from privacy and simplicity perspective, the protocol handler loads stuff from only your own Mastodon instance and you only need to add some extra code to Mastodon. In case of central website, the central website would need to be coded from scratch.

Webfinger based stuff is most standard-close, but UX is complicated, and the required form input would be hard to embed on arbitrary websites

@sandhawke
Copy link

@Gargron Are you saying 2 and 3 are likely to be Mastodon specific because it's always easier to build in your own back yard, or is there some larger reason? Even if only Mastodon folks are interested in working on it right now, making it Mastodon specific seems... odd.

With 3, for instance, the domain could be w3.org or opensocial.org.

@akihikodaki
Copy link
Contributor

akihikodaki commented Jul 3, 2017

Regarding protocol handler:
Even if it is going be implemented as Mastodon-specific protocol, it would be nice if it is implemented in a way close to standards, utilizing of Activity Vocabulary, Activity Streams and possibly WebFinger.
For instance,

web+activity:Follow?object=https%3A%2F%2Furl%2Fto%2Factivity%2Fstreams%2Fperson%2Fobject

Here, it uses Activity Vocabulary and has a link to Activity Streams.

@akihikodaki
Copy link
Contributor

I'm considering to add a handler for application/activity+json and/or one for application/ld+json; profile="https://www.w3.org/ns/activitystreams".

At first I thought it may be difficult because it could not tell whether the type of the activity is Person or not, but the capability to have a different activity type could also be a benefit if we are going to implement a custom handler for them (e.g. implementing a feature to show Note activity with the
normal UI for statuses).

Activity Streams itself works as a descriptive profile, and it would also function as a means to connect online. That is neat, IMHO.

However, that will not allow to execute a specific operation such as follow, favourite, boost, etc. It just enables users to see the content in the Web interfaces of their instances.

To solve the issue, I suggest to implement a custom class named Intent. For example, REMOTE FOLLOW button of @alice@instance would be a link for the following activity:

{
  "@context": "https://www.w3.org/ns/activitystreams",
  "type": "Intent",
  "summary": "Following Alice",
  "target": {
     "type": "Follow",
     "object": {
       "id":   "https://instance/@alice",
       "type": "Person",
       "name": "Alice"
     }
  }
}

For details, see https://akihikodaki.github.io/activity-vocabulary-intent/.

@akihikodaki
Copy link
Contributor

registerContentHandler does not seem to be supported by Chromium, so we still need a custom protocol.

@sandhawke
Copy link

@akihikodaki my demo above, up in my Jun 3 comment, works fine for me in Chromium (on Ubuntu 17.04). It does not however work on Chrome Mobile, which ... as I think about it more, ... makes me think we have to go with option 3 (a neutral domain as a home for some local storage).

Also, I'm not quite sure I follow your approach. Are you aiming to support the use case of seeing whether I'm already following someone, when I'm looking at their profile on their site?

@akihikodaki
Copy link
Contributor

akihikodaki commented Jul 4, 2017

@sandhawke I meant to implement with content type, not URL scheme. Supporing content type makes sense since it is already registered. However, I have just ran the required API on Chromium to find it is not implemented. URL scheme handler is still available for Chromium.

My idea is to describe REMOTE FOLLOW button in Activity Streams. That is it.

@sandhawke
Copy link

So, you're not actually trying to solve the problem of making a nice Remote Follow button, or the other swicg/general#5 stuff ? Or does describing Remote Follow in AS somehow help with these features?

@akihikodaki
Copy link
Contributor

@sandhawke Yes, describing Remote Follow in AS somehow help with these features help. Activity Streams already has a structure to present various activities, including following action, and that could be utilized to deliver an intent. If registerContentHandler were available, we could register a handler to read AS and to execute described actions.

@sandhawke
Copy link

Hm, perhaps. That's pretty far from the hard part of this, though... shrug

@sandhawke
Copy link

I guess the question is if I set things up for a non-Mastodon-specific solution, what would be necessary for Mastodon to adopt it? I could try to get it adopted somewhere a bit simpler first, maybe.

@akihikodaki
Copy link
Contributor

I have written a draft of web+activity+data and web+activity+https specification. They have their literal semantics.
https://akihikodaki.github.io/activity-vocabulary-intent/scheme
It allows to write a link to an intent to follow together with the intent extension.

@akihikodaki
Copy link
Contributor

akihikodaki commented Jul 6, 2017

I have implemented a prototype.

before after
before after

A dialog shown in the right-bottom of the image after the change is asking to choose an application to open.

Source code is at https://github.com/kagucho/mastodon/tree/activity_url.

@KyLeggiero
Copy link

How can I, as a developer, put this on my site?

@rcsilva83
Copy link

rcsilva83 commented Nov 20, 2022

@Gargron, is this still valid? I'd love to see this in use for a better remote follow flow.

Edit: nevermind. I found your answer here.

ClearlyClaire added a commit to ClearlyClaire/mastodon that referenced this issue Jul 13, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api REST API, Streaming API, Web Push API
Projects
None yet
Development

No branches or pull requests

10 participants