this is how easy it is to implement post federation?

This commit is contained in:
April John 2025-02-03 11:34:22 +01:00
parent 44108cb2d3
commit 2401a6f42d
3 changed files with 64 additions and 10 deletions

View file

@ -59,6 +59,34 @@ impl CreatePost {
} }
Ok(()) Ok(())
} }
pub async fn sends(
note: Note,
db_entry: post::Model,
inbox: Vec<Url>,
data: &Data<StateHandle>,
) -> Result<(), Error> {
print!("Sending reply to {}", &note.attributed_to);
let encoded_url = base_url_encode(&note.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] #[async_trait::async_trait]

View file

@ -23,7 +23,7 @@ pub struct DbPost {
pub local: bool, pub local: bool,
} }
#[derive(Deserialize, Serialize, Debug)] #[derive(Deserialize, Serialize, Debug, Clone)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct Note { pub struct Note {
#[serde(rename = "type")] #[serde(rename = "type")]

View file

@ -1,25 +1,21 @@
use crate::{ use crate::{
activities::follow::Follow, activities::{create_post::CreatePost, follow::Follow}, entities::{
entities::{
self, follow_relation, self, follow_relation,
prelude::{self, FollowRelation}, prelude::{self, FollowRelation},
user, user,
}, }, utils::generate_follow_req_id, versia::http::main_versia_url_to_user_and_model, API_DOMAIN, DB, FEDERATION_CONFIG
versia::http::main_versia_url_to_user_and_model,
utils::generate_follow_req_id,
API_DOMAIN, DB, FEDERATION_CONFIG,
}; };
use activitypub_federation::{ use activitypub_federation::{
activity_sending::SendActivityTask, fetch::object_id::ObjectId, protocol::context::WithContext, 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 anyhow::Result;
use sea_orm::{ActiveModelTrait, ColumnTrait, EntityOrSelect, EntityTrait, QueryFilter, Set}; use sea_orm::{ActiveModelTrait, ColumnTrait, EntityOrSelect, EntityTrait, QueryFilter, Set};
use serde::Deserialize; use serde::Deserialize;
use url::Url; use url::Url;
use super::{ 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}, 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<()> { 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::<crate::objects::post::Note>(&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(()) Ok(())
} }
fn get_inbox_vec(ap_note: &crate::objects::post::Note) -> Vec<Url> {
let mut inbox: Vec<Url> = 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
}