wordpress-activitypub
wordpress-activitypub copied to clipboard
Feature Request: Federate only selected Post Formats
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".
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.
I agree with this — it would be nice to have better mechanisms for opting in / out of federation.
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)
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.)
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 good point!
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.
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.
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.)