diff --git a/bp/actors/routes.py b/bp/actors/routes.py index bcb8979..0d2f692 100644 --- a/bp/actors/routes.py +++ b/bp/actors/routes.py @@ -89,6 +89,45 @@ async def _send_accept( log.exception("Failed to send Accept to %s", follower_inbox) +async def _backfill_follower( + actor: ActorProfile, + follower_inbox: str, +) -> None: + """Deliver recent Create activities to a new follower's inbox.""" + from shared.events.handlers.ap_delivery_handler import ( + _build_activity_json, _deliver_to_inbox, + ) + from shared.models.federation import APActivity + + domain = _domain() + + # Fetch recent Create activities (most recent first, limit 20) + activities = ( + await g.s.execute( + select(APActivity).where( + APActivity.actor_profile_id == actor.id, + APActivity.is_local == True, # noqa: E712 + APActivity.activity_type == "Create", + ) + .order_by(APActivity.published.desc()) + .limit(20) + ) + ).scalars().all() + + if not activities: + return + + log.info( + "Backfilling %d posts to %s for @%s", + len(activities), follower_inbox, actor.preferred_username, + ) + + async with httpx.AsyncClient() as client: + for activity in reversed(activities): # oldest first + activity_json = _build_activity_json(activity, actor, domain) + await _deliver_to_inbox(client, follower_inbox, activity_json, actor, domain) + + def register(url_prefix="/users"): bp = Blueprint("actors", __name__, url_prefix=url_prefix) @@ -315,6 +354,9 @@ def register(url_prefix="/users"): # Send Accept await _send_accept(actor_row, body, follower_inbox) + # Backfill: deliver recent posts to new follower's inbox + await _backfill_follower(actor_row, follower_inbox) + async def _handle_undo( actor_row: ActorProfile, body: dict, diff --git a/shared b/shared index a626dd8..9a8b556 160000 --- a/shared +++ b/shared @@ -1 +1 @@ -Subproject commit a626dd849dd35ed4f8f69395d1754817256811bb +Subproject commit 9a8b556c13512d84091c0e01fd746bbfcaf68c71