Fix duplicate AP posts + backfill posts on new follow
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 38s
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 38s
- Stable object IDs per source (no more duplicates) - Dedup Update activities (Ghost double-webhook) - Backfill: deliver recent Create activities to new follower inbox Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -89,6 +89,45 @@ async def _send_accept(
|
|||||||
log.exception("Failed to send Accept to %s", follower_inbox)
|
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"):
|
def register(url_prefix="/users"):
|
||||||
bp = Blueprint("actors", __name__, url_prefix=url_prefix)
|
bp = Blueprint("actors", __name__, url_prefix=url_prefix)
|
||||||
|
|
||||||
@@ -315,6 +354,9 @@ def register(url_prefix="/users"):
|
|||||||
# Send Accept
|
# Send Accept
|
||||||
await _send_accept(actor_row, body, follower_inbox)
|
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(
|
async def _handle_undo(
|
||||||
actor_row: ActorProfile,
|
actor_row: ActorProfile,
|
||||||
body: dict,
|
body: dict,
|
||||||
|
|||||||
2
shared
2
shared
Submodule shared updated: a626dd849d...9a8b556c13
Reference in New Issue
Block a user