From f461f633b340231377e4d4f345050bf61f0b6d19 Mon Sep 17 00:00:00 2001 From: Gabriel Kaszewski Date: Fri, 10 Jul 2026 16:59:46 +0200 Subject: [PATCH] feat: emit OutboundFollowAccepted when remote accepts our follow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit v0.4.2 — consumers can now react to outbound follow acceptance (e.g. import_remote_outbox to backfill). Previously the accept handler silently updated the DB with no event for consumers. --- CHANGELOG.md | 8 ++++++++ Cargo.lock | 2 +- Cargo.toml | 2 +- src/activities/accept.rs | 22 ++++++++++++++++++++-- src/data.rs | 7 +++++++ 5 files changed, 37 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4552d94..7a08010 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## [0.4.2] — 2026-07-10 + +### New features + +- `FederationEvent::OutboundFollowAccepted { local_user_id, remote_actor_url, outbox_url }` — emitted when a remote actor accepts our outbound follow request. Consumers should call `import_remote_outbox(outbox_url, actor_url)` to backfill the remote user's content. Without this event, outbound follow acceptance was silent and consumers had no hook to trigger backfill. + +--- + ## [0.4.1] — 2026-06-30 ### Bug fixes diff --git a/Cargo.lock b/Cargo.lock index 2776668..17e990d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1368,7 +1368,7 @@ dependencies = [ [[package]] name = "k-ap" -version = "0.4.0" +version = "0.4.2" dependencies = [ "activitypub_federation", "anyhow", diff --git a/Cargo.toml b/Cargo.toml index cfbe0f6..d6441de 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "k-ap" -version = "0.4.1" +version = "0.4.2" edition = "2024" description = "Generic ActivityPub protocol layer" license = "MIT" diff --git a/src/activities/accept.rs b/src/activities/accept.rs index 7571809..beedaae 100644 --- a/src/activities/accept.rs +++ b/src/activities/accept.rs @@ -49,14 +49,32 @@ impl Activity for AcceptActivity { } let local_user_id = crate::urls::extract_user_id_from_url(self.object.actor.inner()) .ok_or_else(|| Error::bad_request(anyhow::anyhow!("invalid actor URL in Follow")))?; + let remote_actor_url = self.actor.inner().as_str().to_string(); data.follow_repo .update_following_status( local_user_id, - self.actor.inner().as_str(), + &remote_actor_url, FollowingStatus::Accepted, ) .await?; - tracing::info!(remote_actor = %self.actor.inner(), "follow accepted by remote"); + tracing::info!(remote_actor = %remote_actor_url, "follow accepted by remote"); + + if let Some(publisher) = &data.event_publisher { + let outbox_url = data + .actor_repo + .get_remote_actor(&remote_actor_url) + .await + .ok() + .flatten() + .and_then(|a| a.outbox_url); + let _ = publisher + .publish(crate::data::FederationEvent::OutboundFollowAccepted { + local_user_id, + remote_actor_url, + outbox_url, + }) + .await; + } Ok(()) } } diff --git a/src/data.rs b/src/data.rs index ed695f3..0ba94b3 100644 --- a/src/data.rs +++ b/src/data.rs @@ -41,6 +41,13 @@ pub enum FederationEvent { owner_user_id: uuid::Uuid, follower_inbox_url: String, }, + /// A remote actor accepted our outbound follow request. + /// Call `ActivityPubService::import_remote_outbox(outbox_url, actor_url)` to backfill. + OutboundFollowAccepted { + local_user_id: uuid::Uuid, + remote_actor_url: String, + outbox_url: Option, + }, } /// Receives typed federation events.