From 81adb9b70e0690ac2f27f698514d15bc3f8bae00 Mon Sep 17 00:00:00 2001 From: silverpill Date: Thu, 25 Nov 2021 21:28:06 +0000 Subject: [PATCH] Send Announce(Note) after doing a repost --- src/activitypub/activity.rs | 22 ++++++++++++++++++++++ src/activitypub/receiver.rs | 29 +++++++++++++++++++++++++++++ src/activitypub/vocabulary.rs | 1 + src/mastodon_api/statuses/views.rs | 15 +++++++++++++++ 4 files changed, 67 insertions(+) diff --git a/src/activitypub/activity.rs b/src/activitypub/activity.rs index ef4d934..e9a9f1e 100644 --- a/src/activitypub/activity.rs +++ b/src/activitypub/activity.rs @@ -225,6 +225,28 @@ pub fn create_activity_like( activity } +pub fn create_activity_announce( + instance_url: &str, + actor_profile: &DbActorProfile, + object_id: &str, +) -> Activity { + let object = Object { + context: Some(json!(AP_CONTEXT)), + id: object_id.to_string(), + object_type: NOTE.to_string(), + ..Default::default() + }; + let activity = create_activity( + instance_url, + &actor_profile.username, + ANNOUNCE, + None, + object, + AP_PUBLIC, + ); + activity +} + pub fn create_activity_follow( instance_url: &str, actor_profile: &DbActorProfile, diff --git a/src/activitypub/receiver.rs b/src/activitypub/receiver.rs index 88a0356..aebea0b 100644 --- a/src/activitypub/receiver.rs +++ b/src/activitypub/receiver.rs @@ -295,6 +295,35 @@ pub async fn receive_activity( .map_err(|_| ValidationError("invalid object"))?; process_note(config, db_client, object).await?; }, + (ANNOUNCE, _) => { + let author = get_or_fetch_profile_by_actor_id( + db_client, + &config.instance(), + &activity.actor, + &config.media_dir(), + ).await?; + let object_id = match activity.object.as_str() { + Some(object_id) => object_id.to_owned(), + None => { + let object: Object = serde_json::from_value(activity.object) + .map_err(|_| ValidationError("invalid object"))?; + object.id + }, + }; + let post_id = match parse_object_id(&config.instance_url(), &object_id) { + Ok(post_id) => post_id, + Err(_) => { + let post = get_post_by_object_id(db_client, &object_id).await?; + post.id + }, + }; + let repost_data = PostCreateData { + repost_of_id: Some(post_id), + object_id: Some(object_id), + ..Default::default() + }; + create_post(db_client, &author.id, repost_data).await?; + }, (DELETE, _) => { let object_id = match activity.object.as_str() { Some(object_id) => object_id.to_owned(), diff --git a/src/activitypub/vocabulary.rs b/src/activitypub/vocabulary.rs index 637d5af..a4d7ddf 100644 --- a/src/activitypub/vocabulary.rs +++ b/src/activitypub/vocabulary.rs @@ -2,6 +2,7 @@ // Activity types pub const ACCEPT: &str = "Accept"; +pub const ANNOUNCE: &str = "Announce"; pub const CREATE: &str = "Create"; pub const DELETE: &str = "Delete"; pub const FOLLOW: &str = "Follow"; diff --git a/src/mastodon_api/statuses/views.rs b/src/mastodon_api/statuses/views.rs index 3b74ffb..d3d09d3 100644 --- a/src/mastodon_api/statuses/views.rs +++ b/src/mastodon_api/statuses/views.rs @@ -7,6 +7,7 @@ use uuid::Uuid; use crate::activitypub::activity::{ create_activity_note, create_activity_like, + create_activity_announce, }; use crate::activitypub::actor::Actor; use crate::activitypub::deliverer::deliver_activity; @@ -250,6 +251,20 @@ async fn reblog( let mut post = get_post_by_id(db_client, &status_id).await?; get_reposted_posts(db_client, vec![&mut post]).await?; get_actions_for_posts(db_client, ¤t_user.id, vec![&mut post]).await?; + + // Federate + let maybe_remote_actor = post.author.remote_actor() + .map_err(|_| HttpError::InternalError)?; + if let Some(remote_actor) = maybe_remote_actor { + let object_id = post.object_id.as_ref().ok_or(HttpError::InternalError)?; + let activity = create_activity_announce( + &config.instance_url(), + ¤t_user.profile, + object_id, + ); + deliver_activity(&config, ¤t_user, activity, vec![remote_actor]); + }; + let status = Status::from_post(post, &config.instance_url()); Ok(HttpResponse::Ok().json(status)) }