feat: publish FollowAccepted event when remote accepts follow

This commit is contained in:
2026-05-13 01:28:03 +02:00
parent b1d4b4de2d
commit 2567103587
5 changed files with 31 additions and 1 deletions

View File

@@ -17,3 +17,5 @@ axum = { workspace = true }
activitypub_federation = "0.7.0-beta.11"
url = { version = "2", features = ["serde"] }
enum_delegate = "0.2"
domain = { workspace = true }
reqwest = { workspace = true }

View File

@@ -17,6 +17,7 @@ use crate::actors::DbActor;
use crate::data::FederationData;
use crate::error::Error;
use crate::repository::{FollowerStatus, FollowingStatus};
use domain::{events::DomainEvent, value_objects::UserId};
// --- Follow ---
@@ -141,6 +142,24 @@ impl Activity for AcceptActivity {
FollowingStatus::Accepted,
)
.await?;
if let Ok(Some(outbox_url)) = data
.federation_repo
.get_following_outbox_url(local_user_id, self.actor.inner().as_str())
.await
{
let event = DomainEvent::FollowAccepted {
local_user_id: UserId::from_uuid(local_user_id),
remote_actor_url: self.actor.inner().to_string(),
outbox_url,
};
if let Some(publisher) = &data.event_publisher {
if let Err(e) = publisher.publish(&event).await {
tracing::warn!(error = %e, "failed to publish FollowAccepted event");
}
}
}
tracing::info!(remote_actor = %self.actor.inner(), "follow accepted by remote");
Ok(())
}

View File

@@ -3,6 +3,7 @@ use std::sync::Arc;
use crate::content::ApObjectHandler;
use crate::repository::FederationRepository;
use crate::user::ApUserRepository;
use domain::ports::EventPublisher;
#[derive(Clone)]
pub struct FederationData {
@@ -13,6 +14,7 @@ pub struct FederationData {
pub(crate) domain: String,
pub(crate) allow_registration: bool,
pub(crate) software_name: String,
pub(crate) event_publisher: Option<Arc<dyn EventPublisher>>,
}
impl FederationData {
@@ -23,6 +25,7 @@ impl FederationData {
base_url: String,
allow_registration: bool,
software_name: String,
event_publisher: Option<Arc<dyn EventPublisher>>,
) -> Self {
let domain = base_url
.trim_start_matches("https://")
@@ -39,6 +42,7 @@ impl FederationData {
domain,
allow_registration,
software_name,
event_publisher,
}
}
}

View File

@@ -81,8 +81,12 @@ impl ActivityPubService {
allow_registration: bool,
software_name: String,
debug: bool,
event_publisher: Option<Arc<dyn domain::ports::EventPublisher>>,
) -> anyhow::Result<Self> {
let data = FederationData::new(repo, user_repo, object_handler, base_url.clone(), allow_registration, software_name);
let data = FederationData::new(
repo, user_repo, object_handler, base_url.clone(),
allow_registration, software_name, event_publisher,
);
let federation_config = ApFederationConfig::new(data, debug).await?;
Ok(Self {
federation_config,

View File

@@ -60,6 +60,7 @@ pub async fn wire(
allow_registration,
"movies-diary".to_string(),
cfg!(debug_assertions),
None, // event_publisher wired in Task 6
)
.await?,
);