ActivityPub Plugin

Well, a mastodon user will see it in the context of a timeline, and timelines are generally limited. On mastodon, by default, a total timeline doesn’t exceed 400 posts. If you are looking at the original, you are looking in Discourse anyway. So while it’s true in theory I don’t see it causing actual confusion in practice. You have to already be a follower to see the content; following a link to the original takes you into Discourse where the confusion is resolved.

Not perfect, but perhaps a “least bad” option?

I suppose, as an alternative, you could federate out an edit that annotates the post as superseded by a transfer of ownership, kind of like adding the “discuss this on our forum” link?

Sure, I’m not arguing it’s not a difference, only saying that it seems like an acceptable difference, compared to blocking a useful and utilized Discourse feature.

Deleting the original will orphan threads in the context of other platforms to which you are federating, since you can’t change the actor associated with an activity in an edit (as I understand it).

An alternative might be to stop federating edits at all if the post in Discourse has a different author from when it was first federated. Maybe with a warning? “Changing owner will disable federation for this post, do you really want to proceed?”

Yes. That is what it looks like in Discourse to a normal user, who might not know that they can click the pencil icon and go through changes to review, or doesn’t have permissions. These are ingrained in normal Discourse use, as I see it:

  • Making a post a wiki is saying that you accept others’ edits appearing in normal use under your own name
  • Even if it’s not a wiki, sufficiently-privileged users can edit your post in Discourse, depending on site configuration

From my perspective, this is as close to equivalent as you get, given the differences in underlying model.

As I see it, “click to see post on original site” already shows different content between implementations that are fediverse-first, even ignoring this plugin. Different set of comments visible, different markup, different handling of articles. So some differences being visible through this plugin does not surprise me; I think it’s inevitable.

(Thank you again for your thoughtful consideration of these ideas. I recognize that these are hard boundary cases, I’m grateful for the work, I do not assume that my ideas are best, and I don’t mean to create any sense of obligation for this phase or any phase of work on this, or even to respond to anything in particular that I’m writing.)

1 Like

Like with the category change I think it really depends on the scenario. Consider for example

  1. Post 1 created in Category 1 by User 1 (Actor 1)
  2. Post 1 author changed by User 3 (an admin) to User 2 (Actor 2) 2 minutes later
  3. Category 1 is followed by 400 Actors across 20 domains and 5 different software platforms, each with slightly different implementation of timelines and content discovery.
  4. Within 2 minutes of Post 1 being created there are 2 Notes with identical content and different Actors POST’ed to those 400 Followers.

I think that’s likely to cause confusion for a decent subset of followers, not to mention the fact that User 2 may not even realise that their name is now attached with this duplicate content they didn’t write across 20 different domains. They may be okay with admins doing that on a single instance, it’s somewhat implicitly consented to in posting on that instance, however I think we should be very cautious about extending that implicit consent across the entire fediverse, especially in the imperfect circumstances of duplicating the content. Changing post owners is a powerful administrative function, specific to Discourse, and implicitly tied to the “social contract” of a single instance.

I think the case for wikis is stronger, however I would again observe what you’ve already alluded to. Wikis are a concept ingrained in normal Discourse. Associating the edits of anyone (not just staff) with the original author is a Discourse concept, without an analogue in ActivityPub. We should be cautious about extending that concept using the standard methods of ActivityPub across the entire fediverse. Those Update activities are going to be treated like any other Update activity across many different instances and software platforms, decontextualised from their original wiki context. Moreover, as you’ve also alluded too, there’s already a potential issue in this vein with the ability of staff and highly trusted users to edit the posts of others. I think that more limited question needs more consideration before we get to the question of wikis.

I’m not trying to set up a binary choice between Discourse and ActivityPub for these features. What I’m saying is that we shouldn’t just attempt to map sensitive Discourse functionality onto the Fediverse without cautiously thinking through the consequences. The default should be that these more sensitive features are disabled on ActivityPub posts until we have a bit more confidence that we’re not going to end up harming or surprising a decent subset of users or use cases.

Personally, I don’t feel we’re there yet with either, albeit my gut is that the wiki case has more potential at this stage, even if I don’t quite see a good solution yet.


These two items are now done as well, I just merged @angus’s PR for identity verification via OAuth. Barring bug fixes and performance improvements, this completes the current phase of features added to the plugin.

As it stands, the plugin is quite feature-rich. To recap the main features quickly, the plugin supports:

  • Followers Only post publication in ActivityPub (default is Public)
  • First Post or Full Topic publication (default is First Post)
  • two-way sync when using Full Topic publication, i.e. all Discourse-created posts in a topic will be published in ActivityPub, and vice versa, replies in ActivityPub will be posted to Discourse
  • option to publish posts as Notes (for shorter content services like Mastodon) or Article (more appropriate for long content services)
  • identity verification

Next up we will work on fine-tuning the current features, improving usability. Feedback is still welcome, of course. I am particularly interested in ways to explain how all this works to regular users, it’s not an easy feat.

I’m very much on the same page as @angus, our goal is to do what’s practical and achievable with a reasonable amount of effort. To that effect, we’re willing to accept some reduced functionality in Discourse at this time. That’s our best bet to find out if specific limitations are important to address or not (for example, will the plugin users often run into wiki-ActivityPub limitations?).


Do I understand correctly, then, that we’re at the point where it makes sense to articulate the restrictions?

Hi there :slight_smile:

First, thanks for developing all this.

Then, I am really interested in connecting different ActivityPub services together, and as far as I read, is this mostly about sending messages from Discourse to Mastodon back and forth.

I am aware, that the protocol is service-agnostic, but is there any kind of documentation, to, let’s say, connect different Discourse instances, or integration of Nextcloud, or Peer Tube, etc.?

1 Like

We have disabled post author changes and wikis in ActivityPub topics for now for the reasons I’ve already mentioned (their assumptions don’t work with ActivityPub out-of-the-box). Those are the only two features that have been temporarily disabled in ActivityPub topics in this fashion. Any other reduced functionality should be reported as an issue.

This is an ActivityPub plugin that closely follows the ActivityPub specification, so it is designed to work with any service that follows that specification, which includes all of those you’ve mentioned (and others). Mastodon is the first ActivityPub platform we’ve focused on integrating with because, practically speaking, you have to ensure compatibility with one service at a time and it’s the largest ActivityPub platform.


Tried twice at

	"errors": ["You are not permitted to view the requested resource."],
	"error_type": "invalid_access"

What do I do?


Hey @rokejulianlockhart, thanks for the feedback. How are you performing the authorization flow? Are you clicking “Authorize” in the above screenshot in a browser (also which browser?) Or are you copy / pasting the urls in some fashion? I ask because you’ve got them there in your post. Here’s a video of the standard flow working for me on

Are you doing anything different from that?



  1. image

  2. image

  3. image

    You are about to log in to the site “” with the username “rokejulianlockhart”, but the web site does not require authentication. This may be an attempt to trick you.

    Is “” the site you want to visit?

    Here I click


  4. Log in - Mastodon

    Authorization required would like permission to access your account. It is a third-party application. If you do not trust it, then you should not authorize it.
    Review permissions

    Read-only access

    Here I click


  5. Then the previous

    Is “” the site you want to visit?

    prompt appears, and I do the same.


    1. .JSON

      {"errors":["You are not permitted to view the requested resource."],"error_type":"invalid_access"}
    2. Headers

      X-Firefox-Spdy: h2
      content-encoding: gzip
      content-type: application/json; charset=utf-8
      date: Mon, 25 Sep 2023 11:39:30 GMT
      referrer-policy: strict-origin-when-cross-origin
      server: nginx
      vary: Accept-Encoding
      x-content-type-options: nosniff
      x-discourse-route: o_auth/redirect
      x-discourse-username: rokejulianlockhart
      x-download-options: noopen
      x-frame-options: SAMEORIGIN
      x-permitted-cross-domain-policies: none
      x-request-id: 01276bd6-77ea-42ae-8f60-6fa365a70e1f
      x-xss-protection: 0
      Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
      Accept-Encoding: gzip, deflate, br
      Accept-Language: en-GB,en;q=0.7,en-US;q=0.3
      Connection: keep-alive
      Sec-Fetch-Dest: document
      Sec-Fetch-Mode: navigate
      Sec-Fetch-Site: cross-site
      Sec-Fetch-User: ?1
      Upgrade-Insecure-Requests: 1
      User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/117.0

Hello, after the latest update, it seems to break user profiles (/u/user). The username and profile picture would show up (plus the list of user offensives at the top)

We went through our plugins list and disabled each one one by one until the problem went away. It also worked with safe mode enabled. Here are some of the client errors we would get:

Cannot read properties of null (reading 'getBoundingClientRect')
at Object.offset (
at e.scrolled (
at p.invoke (
at p.flush (
at h.flush (
at $._end (
at $.end (
at $._runExpiredTimers (

Here is what it looks like with the plugin enabled (for your own account)

For another user (in this case, 9pfs)

Here’s another funny bug caused by the plugin:

We’re currently running 3.2.0.beta2-dev from this commit and we are running version 0.1.0 of the plugin from this commit.

1 Like

@rokejulianlockhart Do you have cookies disabled or some kind of privacy extension running? The authorization flow currently relies on a secure session cookie to work.

@aboutDavid Thanks for the report. While it’s possible, it seems unlikely that what you’re sharing is being caused by an issue in this plugin. Could you share a link to your site? Also do you have any themes or theme components enabled?


From safe mode troubleshooting, we know the following for certain:

  1. It’s an unofficial plugin
  2. It is not a theme or theme component.

As far as I’m aware, we have two unofficial plugins:

  1. Animate avatars (Manually confirmed not to be the culprit)
  2. ActivityPub

As for a site link:


The upgrade UI shows a checkmark next to all plugins other than those two (indicating that they are official plugins).


The issue on your site is likely being caused by something using the user-profile-avatar-flair plugin outlet. This plugin doesn’t use that outlet. The animated avatars plugin does however.

How did you confirm this?

1 Like

@aboutDavid checked and made sure that the plugin had no client-side JS. Is the issue partly server-side?

1 Like

No client-side js doesn’t necessarily mean no client-side issues. In this case the issue seems to be arising from the way a plugin outlet is being used, possibly in a template. Could you try removing the animated avatars plugin and let me know the result?

(As an aside, the Animated Avatars Plugin does have client-side js. See for example).

1 Like

I just went to edit a category here on Meta (to change some group access permissions). I didn’t change any activitypub-related settings, but we ended up with these three entries in the staff log:

I guess they technically went from nil to their default value, so there is no actual change in behaviour? Still, it would be good to avoid this remove logging to avoid confusion.


Thanks for the report David, I’ll take a look soon.

1 Like

whoopsy, i’m a little dumb today, apologies

edit: yeah it’s most likely animated avatars, sorry for wasting your time lol


@angus, not that I know of.

and I ensured that I disabled uBlock Origin, not that I use the privacy lists anyway.

However, I’ve encountered a different issue testing this today.

Log in - Mastodon

Client authentication failed due to unknown client, no client authentication included, or unsupported authentication method.