Secret Text Plugin

I posted this in the Dev section because I do not think such a plugin exists. If I’m wrong, I would love to be corrected.

I would like to create a Discourse plugin that allows ‘secret’ text in the midst of a post. This would enable Play by Post RPG games where players interact privately without requiring an unwieldy number of threads.

The idea is that you can post with [secret=username1,username2]text[/secret] and it would only appear to the poster and those specified. For now, we will ignore overrides such as Admins / Thread starters, etc.

Is there documentation on the Discourse Rails app structure? Are there endpoints I can hook into, callbacks I can register, etc that make something like this easy? I’d rather not go digging through dozens of files to try to find the right place and learn Rails all at the same time, not if one of you kind folk can point me to the easy way.

I would naively expect that, at worst, I can override the default renderer for posts and filter out secret tags without the request user. Is there a way to register functionality like that (middleware)? Or do I need to go spelunking into the bowels of Discourse?

2 Likes

Why not just use the two forms of existing spoiler text?

Or link to other topics in categories that only those people have access to.

  1. If the game pits the players against each other, they will be tempted to cheat and look. And if they AREN’T pit against each other, they’ll peek and argue they aren’t cheating. :slight_smile: In other words, I want only those intended to read it to be able to.

  2. In short, that’d be extremely unwieldy due to a combinatoric explosion. Imagine 6 players. Just to have each player be able to privately talk to each other you’d need (6 choose 2) categories. 3 people want to talk to each other? That’s 6 choose 3, etc. You get the idea.

As an interested bystander who is not going to be writing this, I have some questions.

To Logan: how secret is secret? Is “view source” visible too public?

To those who know Discourse’s internals: Could the username be exposed as a CSS class (probably with a known prefix)? My thinking is the [secret] block could be set to invisible by default, and exposed for particular users.

I strongly suspect username can be exposed that way, but that it is not currently.

Preferably not. Most of them have even done some web development so CTRL+SHIFT+I is not a very good barrier to entry.

At best, I’d tolerate the text existing in some Ember js variable. If they don’t know how it works and can’t see the HTML, they’d likely assume it was done server side.

Server side would be better still. There isn’t an easy way to inject a middleware renderer on the post text that has access to the current user context?

I don’t think middleware rendering would be the answer here; the cooked post is stored in the database and serialized out over API, so your options begin basically at the serializer (post_serializer.rb) on the way out.

Two potential options:

  • server side: The serializer knows the current user and could manipulate cooked as it leaves the server. Problems, though: this strikes me as slow as hell, since it’ll have to perform a search-and-possible-replace through every chunk of text that’s getting serialized, which is a lot. It also gets really hairy for live updating, since in that case you’re serializing posts, but you don’t know who they’re going to.

  • client side: When cooking the post, you introduce a secret tag with username attributes, which get deleted from the markup upon hitting the server.

<p data-secret data-reveal-user1 data-reveal-user2>Some secret text</p>
# At some point after the post is rendered, I guess?
$('[data-secret]').not(`[data-reveal-${Discourse.User.current().username}]`).remove()

Unfortunately, someone who’s a bit savvy could still see the cooked text as it comes over in the network request.

Can a plugin extend the post model to include a ‘secret’ flag to indicate which posts need preprocessing? You’d need to also patch any updating to set the secret flag, but that doesn’t sound too awful.

edit: and how slow would it actually be? Is Ruby’s regex in Ruby or C?

1 Like

I Need this plugin too :frowning: