From 2401a6f42d2e916d4935312c19c14469229932e4 Mon Sep 17 00:00:00 2001 From: April John Date: Mon, 3 Feb 2025 11:34:22 +0100 Subject: [PATCH] this is how easy it is to implement post federation? --- src/activities/create_post.rs | 28 ++++++++++++++++++++++ src/objects/post.rs | 2 +- src/versia/inbox.rs | 44 ++++++++++++++++++++++++++++------- 3 files changed, 64 insertions(+), 10 deletions(-) diff --git a/src/activities/create_post.rs b/src/activities/create_post.rs index 09a49a3..0c6078d 100644 --- a/src/activities/create_post.rs +++ b/src/activities/create_post.rs @@ -59,6 +59,34 @@ impl CreatePost { } Ok(()) } + pub async fn sends( + note: Note, + db_entry: post::Model, + inbox: Vec, + data: &Data, + ) -> Result<(), Error> { + print!("Sending reply to {}", ¬e.attributed_to); + let encoded_url = base_url_encode(¬e.id.clone().into()); + let create = CreatePost { + actor: note.attributed_to.clone(), + to: note.to.clone(), + object: note, + kind: CreateType::Create, + id: generate_create_id(data.domain(), &db_entry.id, &encoded_url)?, + }; + let create_with_context = WithContext::new_default(create); + let sends = SendActivityTask::prepare( + &create_with_context, + &data.local_user().await?, + inbox, + data, + ) + .await?; + for send in sends { + send.sign_and_send(data).await?; + } + Ok(()) + } } #[async_trait::async_trait] diff --git a/src/objects/post.rs b/src/objects/post.rs index 506f12d..646cc92 100644 --- a/src/objects/post.rs +++ b/src/objects/post.rs @@ -23,7 +23,7 @@ pub struct DbPost { pub local: bool, } -#[derive(Deserialize, Serialize, Debug)] +#[derive(Deserialize, Serialize, Debug, Clone)] #[serde(rename_all = "camelCase")] pub struct Note { #[serde(rename = "type")] diff --git a/src/versia/inbox.rs b/src/versia/inbox.rs index 88b33ff..13f6eb6 100644 --- a/src/versia/inbox.rs +++ b/src/versia/inbox.rs @@ -1,25 +1,21 @@ use crate::{ - activities::follow::Follow, - entities::{ + activities::{create_post::CreatePost, follow::Follow}, entities::{ self, follow_relation, prelude::{self, FollowRelation}, user, - }, - versia::http::main_versia_url_to_user_and_model, - utils::generate_follow_req_id, - API_DOMAIN, DB, FEDERATION_CONFIG, + }, utils::generate_follow_req_id, versia::http::main_versia_url_to_user_and_model, API_DOMAIN, DB, FEDERATION_CONFIG }; use activitypub_federation::{ activity_sending::SendActivityTask, fetch::object_id::ObjectId, protocol::context::WithContext, }; -use activitystreams_kinds::activity::FollowType; +use activitystreams_kinds::{activity::FollowType, public}; use anyhow::Result; use sea_orm::{ActiveModelTrait, ColumnTrait, EntityOrSelect, EntityTrait, QueryFilter, Set}; use serde::Deserialize; use url::Url; use super::{ - conversion::versia_user_from_db, + conversion::{db_user_from_url, receive_versia_note, versia_user_from_db}, http::{versia_url_to_user, versia_url_to_user_and_model}, }; @@ -133,7 +129,37 @@ async fn follow_request(follow: super::objects::Follow) -> Result<()> { } async fn federate_inbox(note: super::objects::Note) -> Result<()> { - + let db_user = db_user_from_url(note.author.clone()).await?; + let note = receive_versia_note(note, db_user.id).await?; + + let ap_str = note.ap_json.clone().unwrap(); + let ap_note = serde_json::from_str::(&ap_str)?; + + tokio::spawn(async move { + let conf = FEDERATION_CONFIG.get().unwrap(); + let inbox = get_inbox_vec(&ap_note); + + let res = CreatePost::sends(ap_note, note, inbox, &conf.to_request_data()).await; + if let Err(e) = res { + panic!("Problem federating: {e:?}"); + } + }); Ok(()) +} + +fn get_inbox_vec(ap_note: &crate::objects::post::Note) -> Vec { + let mut inbox: Vec = Vec::new(); + + for entry in ap_note.to.clone() { + if entry.to_string().eq_ignore_ascii_case(public().to_string().as_str()) { + let (_, mentions) = ap_note.to.split_at(2); + inbox.append(&mut mentions.to_vec()); + } else { + let (_, mentions) = ap_note.to.split_at(1); + inbox.append(&mut mentions.to_vec()); + } + } + + inbox } \ No newline at end of file