Chats are now federating as limited-visibility posts on the fediverse
-
tl;dr — you can now send me DMs. I blatently and unforgivingly abused the NodeBB chat system to make this work.
Ever since I started this project at the start of 2024, I knew that posts with limited visibility were going to be a sore spot. ActivityPub has the concept of "addressing", with the following valid entries:
- An actor (
as:Person
or similar) uri - A followers collection (?!?!?!)
- The public collection
However, posts and topics in NodeBB have their privileges and access scoped to the category, which meant that while it is able to restrict visibility/posting/etc. to specific users, the system was not flexible enough to handle individual posts with different user visibilities.
Given that limitation, up until this week, if your object did not contain the public collection
https://www.w3.org/ns/activitystreams#Public
, it was automatically and unceremoniously dropped because there was no way NodeBB could display it to the targeted user without leaking it to other users.I had gone through a couple iterations to try to figure out a way to make this work, but none stuck (see the follow-up technical post for more details), and I had just about relegated it to the "think on this for awhile" pile until a recent post by @[email protected] got me thinking outside of the box:
and your forums, direct messages, and inbox can have different feature sets.
Emphasis mine.
Unlike topics and posts, NodeBB's chat system is not constrained by the privilege system, and each chat room has its own collection of members, which in many ways made it a better fit!
I put together a proof-of-concept in a couple days, and we're test driving it now. So my apologies if in the past year you tried to DM me, and I didn't respond. I wasn't ignoring you, NodeBB just didn't know how to handle it, promise!
- An actor (
-
Here's how NodeBB's chat system differs from other ActivityPub implementations that you might be aware of (*ahem hem* Mastodon):
- NodeBB will accept and parse all non-public objects, but (for now) only sends out responses directly to recipients (aka "mentioned only")
- That means "Followers only" posts are accepted but responses are scoped to the individuals themselves (no followers)
- Mastodon has something called "unlisted" or "quiet public". These are still technically public and are parsed the same as any other topic/post.
- Mastodon uses "mentions" as a form of addressing, and so the non-public notes are always addressed to the same set of people who are mentioned.
- NodeBB does not do this. You can mention whoever you want without the message accidentally leaking out because who you mention is different from who is in the chat room.
- If NodeBB receives a response to a chat message and it contains fewer recipients than expected, it will start a new chat room for privacy.
- Conversely, if a response contains more recipients, then that user will be added to the chat room.
- NodeBB will accept and parse all non-public objects, but (for now) only sends out responses directly to recipients (aka "mentioned only")
-
Read on for the technical stuff regarding limited visibility content.
The actual nuts-and-bolts of this system were actually fairly straightforward. Each chat room contains a member list, and when messages are sent in each chat room, we simply address and federate the note out directly to those users.
When posts come in, they go through a different logic path from public posts. Instead of a new reply/topic, they get added to a chat room, or if the visibility scope is narrowed (addressed to fewer people), then a new chat room is created.
There were multiple iterations in my attempts to get this to work.
Post Visibility
The first attempt involved each post maintaining its own list of recipients. Soon afterwards, it was determined that this would not scale well, and cause pagination issues similar to how NodeBB's soft-deleted posts are handled.
Topic visibility
The second attempt was to limit the visibility of posts within a topic. This made the most sense to start with as public objects as sent and received via ActivityPub are parsed as posts (and groups together into topics).
I quickly ran into database limitations because NodeBB is built on a NoSQL database abstraction. What would be straightforward (i.e. a join against a visibility table) became very very complicated as a lot of that optimized query work is not available with free-form NoSQL structures.
The reality would be that utilising the existing organizational structure (categories, topics, and posts) would end up causing so much overhead and data duplication that the fragility of the system made it an ultimate no-go.
Chats
Once I realized that we could potentially use the chats system for limited visibility, I set about building that proof-of-concept. Having built the chat system some 8ish years ago, I remembered that each user maintained their own collection of message ids per room — perfect! Each chat room's users could simply maintain their own set of messages they were allowed to view.
Alas, the chat system had actually been refactored for performance and simplicity by @baris, and this was no longer the case. Messages were more simply retrieved by timestamp from their chat room join date, which meant I needed to take an alternative approach.
Thankfully, I was able to sidestep that particular problem and altered the behaviour so that if incoming messages narrowed visibility, then a new chat room was created.
-
Wow, that's great to see! And this in particular ...
You can mention whoever you want without the message accidentally leaking out because who you mention is different from who is in the chat room.
... is a very good call.
@[email protected] -
@[email protected] I've made this same mistake myself (although not in a leaking way). I removed the mentions in a reply and wondered why they didn't get my response!
The fact that this is a UX stumbling block that gets hit by users again and again and again means it's not a great UX!
-
@[email protected] yeah, horrible UX. talk about violating the principle of least surprise! it's happened to me more than once.
Sharkey bizarrely has almost the inverse UX problem. The 'to' list is separate, as it should be ... but if it's more than a couple of people it extends off the right side of the screen (at least in Firefox) and there's no way to scroll. So I replied to a DM that had five people in it, deleted their mentions from the main text ... and still replied to them because they were on the To line, just not visible.
And then I'm pretty sure that if you DM reply on Mastodon to the Sharkey message, accounts show up in the reply even though there's absolutely no evidence that they were on the message you were replying to (because the mentions weren't there in the text, and Mastodon doesn't show a separate To line, or something like that). @[email protected] I think you ran into this as well?
Easy. Just like email. Yeah right. lolsob. -
It would be nice if Direct Messages (DMs) or Private Messages (PMs) were treated like email and only sent to the people you are sending it to.
But generally, on most platforms, if you mention someone in the top level post, they are assumed to be on the recipient list. (Note, some platforms, like Mastodon, treat every post as if it were a top level post.)
Hubzilla has more privacy features, which prevents your messages from leaking to others, but part of that is because we use the Zot protocol between Hubzilla instances, and can set privacy at the thread level (i.e. the permissions of the top level post is the permissions for the entire thread).
When the same conversation is sent via ActivityPub, we lose a lot of control over the privacy of that post. We can and do address it to specific recipients, but other platforms don't have the same types of access controls, which means we can't enforce the access control list for that conversation on those platforms. -
Seems to work! WHy did you think it didn't?
EDIT: oh wait, this is actually an unlisted post, it didn't work, I was confused. I'll try from a mastodon account.
@[email protected] -
@[email protected] no, no, i just edited my post, I was confused ... in fact it wasn't working, I'll try from a Mastodon account
-
Speaking of the principle of least surprise ... @jdp23 is post got auto-boosted by @activitypub but there wasn't anything that indicated to me that was going to happen.
And, from GoToSocial, the topic's subject shows up nicely from Julian, @jdp23's reply lost the topic, but it showed back up in Julian's reply to the (topicless) reply ... Behavior's similar on Sharkey, although the subject doesn't render as nicely (but it's still readable)
With the @thenexusofprivacy account on Glitch, the subjects don't show up at all -- not even in Julian's original post.
@stefan @julian -
The Nexus of Privacyreplied to The Nexus of Privacy on last edited by [email protected]
And also speaking of violations of the principle of least surprise: it's interesitng to look at how these posts do and don't show up on the Discourse thread at https://socialhub.activitypub.rocks/t/chats-are-now-federating-as-limited-visibility-posts-on-the-fediverse/4650/15 ...
Julian's posts are all fine, no surprise, but a good sign for Discourse/NodeBB federation.
@jdp23's posts show up twice on that thread.
@nexus 's post didn't show up on that thread. So on average, my posts are getting there one, which is good, but the standard deviation's higher than I'd like.
Now how about this post from Mastodon?
-
-
Stefan Bohacekreplied to Stefan Bohacek on last edited by
-
Stefan Bohacekreplied to The Nexus of Privacy on last edited by
@thenexusofprivacy @jdp23 @nexus @julian Hah, yeah, seeing mine!
Even though I've been in the fediverse for over a year now, and I'm pretty used to folks from different platforms talking to each other, it's still pretty fascinating to see this between platforms that I don't typically interact with.
Had the same sort of an "aha moment" with Lemmy not too long ago!
-
The Nexus of Privacyreplied to Stefan Bohacek on last edited by
Yeah, it's amazing when it works. When I tag a Lemmy community in a pst here and it actually shows up as a thread there, it's very cool.
Unfortunately half the time I tag a Lemmy community it doesn't show up as a post there, and there's never indication way. So it's not always amazing. But still, it's amazing when it works!
-
Jupiter Rowlandreplied to Stefan Bohacek on last edited by@Stefan Bohacek @jdp23 @julian "Shadow mentioning" is a thing. (streams) and Forte do it to avoid clutter. Mentions don't have to be visible in a post/comment to work.