Skip to content

Fediverse: federate reposts as Announce #910

Description

@wintermeyer

TL;DR A repost (boost) by a federating member is invisible to their Mastodon followers — repost_post/2 has no federation hook. Emit an Announce on repost and Undo(Announce) on un-repost. Split out of #843 (Part 1); parent tracker #784.

Where: Vutuv.Posts.repost_post/2 + unrepost_post/2 (lib/vutuv/posts.ex, ~line 647); activity builders in VutuvWeb.Fediverse.Docs; enqueue + gates in Vutuv.Fediverse.maybe_federate/2. Architecture: docs/architecture/fediverse.md.

Now: repost_post/2 inserts the PostRepost row and only broadcasts the in-app feed event (broadcast_new_repost/1); unrepost_post/2 deletes the row. Neither federates — unlike create_post/update_post/delete_post, which call Vutuv.Fediverse.federate_*. So a boost never leaves vutuv.

Want:

  • Reposting enqueues an Announce to the reposter's Fediverse followers, but only when all three hold: (1) the reposter federates (Vutuv.Fediverse.federated?/1), (2) the reposted post is fully public (Vutuv.Posts.restricted?/1 false — already guaranteed at repost time by check_visibility_lock/2), (3) the original author federates too — the Announce object is the original Note's id (https://<host>/<author>/posts/<id>); for a non-federating author that URL serves no Note, so Mastodon could not render the boost.
  • Un-reposting enqueues the matching Undo(Announce).
  • Activity ids must be stable so the Undo references the same Announce (e.g. <note-url>#announce-<reposter-username>).
 reposter's followers' servers
        ^
        |  Announce { object: https://<host>/<original-author>/posts/<id> }
        |
  repost_post/2   -> Vutuv.Fediverse.federate_repost(post, reposter)
  unrepost_post/2 -> Vutuv.Fediverse.federate_unrepost(post, reposter)

Notes for someone new to the code:

  • Hook inside repost_post/2 where both the %PostRepost{} and the original %Post{} (with post.user_id) are in scope — broadcast_new_repost/1 alone doesn't know the original author.
  • Follow the shape of Vutuv.Fediverse.maybe_federate/2 for the federated?/public gates and the delivery-queue enqueue.
  • Tests: test/vutuv/posts_federation_test.exs covers the existing Create/Update/Delete hooks — use it as the template. Start with a test (project rule).

Acceptance:

  • Repost by a federating member of a federating member's public post → one Announce per distinct follower inbox; un-repost → Undo(Announce) with a matching id.
  • Repost of a non-federating author's post, or by a non-federating member → nothing enqueued.
  • mix precommit green; any new gettext strings ship with German translations.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions