2 activities::{generate_activity_id, send_lemmy_activity},
4 protocol::activities::following::{accept::AcceptFollow, follow::Follow},
6 use activitypub_federation::{
8 kinds::activity::AcceptType,
9 protocol::verification::verify_urls_match,
10 traits::{ActivityHandler, Actor},
12 use lemmy_api_common::context::LemmyContext;
13 use lemmy_db_schema::{source::community::CommunityFollower, traits::Followable};
14 use lemmy_utils::error::LemmyError;
18 #[tracing::instrument(skip_all)]
19 pub async fn send(follow: Follow, context: &Data<LemmyContext>) -> Result<(), LemmyError> {
20 let user_or_community = follow.object.dereference_local(context).await?;
21 let person = follow.actor.clone().dereference(context).await?;
22 let accept = AcceptFollow {
23 actor: user_or_community.id().into(),
24 to: Some([person.id().into()]),
26 kind: AcceptType::Accept,
27 id: generate_activity_id(
29 &context.settings().get_protocol_and_hostname(),
32 let inbox = vec![person.shared_inbox_or_inbox()];
33 send_lemmy_activity(context, accept, &user_or_community, inbox, true).await
37 /// Handle accepted follows
38 #[async_trait::async_trait]
39 impl ActivityHandler for AcceptFollow {
40 type DataType = LemmyContext;
41 type Error = LemmyError;
43 fn id(&self) -> &Url {
47 fn actor(&self) -> &Url {
51 #[tracing::instrument(skip_all)]
52 async fn verify(&self, context: &Data<LemmyContext>) -> Result<(), LemmyError> {
53 verify_urls_match(self.actor.inner(), self.object.object.inner())?;
54 self.object.verify(context).await?;
55 if let Some(to) = &self.to {
56 verify_urls_match(to[0].inner(), self.object.actor.inner())?;
61 #[tracing::instrument(skip_all)]
62 async fn receive(self, context: &Data<LemmyContext>) -> Result<(), LemmyError> {
63 insert_activity(&self.id, &self, false, true, context).await?;
64 let community = self.actor.dereference(context).await?;
65 let person = self.object.actor.dereference(context).await?;
66 // This will throw an error if no follow was requested
67 let community_id = community.id;
68 let person_id = person.id;
69 CommunityFollower::follow_accepted(&mut context.pool(), community_id, person_id).await?;