wordpress-activitypub icon indicating copy to clipboard operation
wordpress-activitypub copied to clipboard

Feature Request: Federate only selected Post Formats

Open jsit opened this issue 1 year ago • 6 comments

What

I would like to federate only certain Post Formats -- for instance, Status and Aside.

Why

The Standard Post Format is often a long blog post that one might not want to federate. Limiting federation to selected Post Formats would allow a user to only federate Status posts, for instance.

How

A section similar to the "Supported post types" in settings: "Supported post formats".

jsit avatar Mar 06 '24 15:03 jsit

I'd love to have a hook just prior to scheduling (and also just prior to rendering the JSON template) that would let developers "opt out" of "ActivityPub," so that they could exclude based on all sorts of terms, categories, formats ... anything, really.

Like, somewhere here or so https://github.com/Automattic/wordpress-activitypub/blob/master/includes/class-scheduler.php#L120-L129

Ideally, this check is repeated before actually federating (which may very well be delayed). Right now, a "private" post that was public when it was first published, may still end up being sent to followers: https://github.com/Automattic/wordpress-activitypub/issues/631

If you wanted to have an explicit post format setting, that's fine too. The checks would be in the same place, more or less.

Update: As I type this, I'm just noticing https://github.com/Automattic/wordpress-activitypub/blob/1f22ad85f6f261a8cd0a359e17b905c0974219df/includes/transformer/class-factory.php#L50

Would it be possible to use this and just return, e.g., false for objects that one would not want to federate? Because that would be great!

Update 2: Looks like $transformer is still used down the line, even if it happens to be a \WP_Error object? https://github.com/Automattic/wordpress-activitypub/blob/1f22ad85f6f261a8cd0a359e17b905c0974219df/includes/class-activity-dispatcher.php#L70 Might wanna add just one extra line, check that no error occurred? Or maybe it isn't needed, I didn't actually get to test this.

Either way, would be super cool if we could just "short circuit/bypass" the whole ActivityPub thing for posts we don't want to federate.

janboddez avatar Mar 13 '24 15:03 janboddez

I agree with this — it would be nice to have better mechanisms for opting in / out of federation.

mdingemanse avatar Mar 16 '24 09:03 mdingemanse

Might wanna add just one extra line, check that no error occurred? Or maybe it isn't needed, I didn't actually get to test this.

Had another look and if $transformer in class-factory.php is "falsey" (e.g., false or null) then the code will fall back to a "default" transformer, which depends on the post type. If it is not an instance of Base or any of its subclasses, however, then that bit of code will return a WP_Error. Except that the rest of the code then goes on and treats it like a transformer instance. Always.

In my view, any code that calls \Activitypub\Transformer\Factory::get_transformer() should probably confirm that it really is a valid transformer, and exit/return early if it isn't.

(A PHP dev could then "abuse" that hook to bypass federation based in post type or format or category, etc. Not yet sure if we could also use it to fix https://github.com/Automattic/wordpress-activitypub/issues/631#issuecomment-1901083604)

janboddez avatar Mar 18 '24 12:03 janboddez

Finally got the chance to play with this a bit.

Used a must-use (test) plugin like this:

<?php

add_filter( 'activitypub_transformer', function ( $transformer, $object, $class ) {

  // By default, `$transformer` equals `null`. *Unless* we return a "truthy"
  // value, the ActivityPub plugin will fall back to a default transformer.
  // Unfortunately, returning anything other than a valid transformer will
  // lead to a fatal PHP error.

  // Assume this worked, though, and we did not want to federate posts in the
  // "Disable ActivityPub" category (or a certain post format, etc.).

  if ( $object instanceof \WP_Post && in_category( 'disable-activitypub', $object ) ) {
    return 'Random string'; // This will cause `\Activitypub\Transformer\Factory::get_transormer()` to return a `\WP_Error`.
                            // Unfortunately, the rest of the code doesn't actually
                            // detect for this, will choke and throw a fatal error.
                            // If there were proper error checks, we could return
                            // random "truthy" values and effectively disable federation
                            // as well as (in theory) content negotiation.
  }

  return $transformer;

}, 10, 3 );

Right now, get_transformer() is called in exactly 4 places in the code. If we added the right error checks there, we could use this exact hook to effectively disable ActivityPub for certain terms, etc. (Of course, there might be other challenges, like possible race conditions [again, like in #631]; if so, those would have to be tackled separately.)

(I get that this may not be the intended use of the hook, but it'd allow devs to address a couple questions that keep popping up.)

janboddez avatar Mar 23 '24 18:03 janboddez

If we added the right error checks there, we could use this exact hook to effectively disable ActivityPub for certain terms, etc.

Like, if any filter callback returned null (or if there isn't any callback), that could be interpreted as "use the default." If a custom transformer was returned, of course it should be used instead.

If a callback returned, e.g., false, however, or an error, this could be seen as "do not federate."

It wouldn't be too hard to rewrite the code in this manner, and it would be fully backwards compatible.

(In fact, get_transformer() is already set up for some kind of "error scenario" even today. But the rest of the code is seemingly unaware.)

janboddez avatar Mar 25 '24 07:03 janboddez

@janboddez good point!

pfefferle avatar Mar 25 '24 07:03 pfefferle

This issue is stale because it has been open 120 days with no activity. Remove stale label or comment or this will be closed in 5 days.

github-actions[bot] avatar Jul 24 '24 01:07 github-actions[bot]

Bump. I installed this on a new blog I set up, but the inability to specify which posts to federate means I have no way to soft-publish posts (e.g. to backfill old ones) without toggling federation globally.

vivlim avatar Sep 08 '24 23:09 vivlim

I know it may sound like self promotion, so sorry for that, but would the "local-only category" feature of https://github.com/janboddez/addon-for-activitypub/ work for you? I mean, feel free to test, etc.

Works by, prior to federation (and also as part of the "content negotiation" bit during later lookups), checking against this category (that you can totally set yourself). The code itself is slightly "hacky" in order to make it work with Gutenberg, too. (Which is also why I've been holding off on trying to push it to this plugin itself.) Afraid it's the only way, though.

And it could probably be refactored to work with post formats too, but I haven't got around to it, yet. Just thought maybe the idea of using a category instead of a post format isn't all that weird.

(Of course the risk of using yet another plugin is that, well, it could potentially break, if somehow the hooks it relies on, you know, got removed or something.)

janboddez avatar Sep 09 '24 19:09 janboddez