]> Untitled Git - lemmy.git/blob - crates/apub/src/activities/community/announce.rs
62e7c56fd5a15b3a006fe93c3049393111fb288a
[lemmy.git] / crates / apub / src / activities / community / announce.rs
1 use crate::{
2   activities::{
3     community::list_community_follower_inboxes,
4     generate_activity_id,
5     send_lemmy_activity,
6     verify_activity,
7     verify_is_public,
8   },
9   activity_lists::AnnouncableActivities,
10   fetcher::object_id::ObjectId,
11   http::is_activity_already_known,
12   insert_activity,
13   objects::community::ApubCommunity,
14   protocol::activities::community::announce::AnnounceActivity,
15 };
16 use activitystreams::{activity::kind::AnnounceType, public};
17 use lemmy_apub_lib::{
18   data::Data,
19   traits::{ActivityFields, ActivityHandler, ActorType},
20 };
21 use lemmy_utils::LemmyError;
22 use lemmy_websocket::LemmyContext;
23 use url::Url;
24
25 #[async_trait::async_trait(?Send)]
26 pub(crate) trait GetCommunity {
27   async fn get_community(
28     &self,
29     context: &LemmyContext,
30     request_counter: &mut i32,
31   ) -> Result<ApubCommunity, LemmyError>;
32 }
33
34 impl AnnounceActivity {
35   pub async fn send(
36     object: AnnouncableActivities,
37     community: &ApubCommunity,
38     additional_inboxes: Vec<Url>,
39     context: &LemmyContext,
40   ) -> Result<(), LemmyError> {
41     let announce = AnnounceActivity {
42       actor: ObjectId::new(community.actor_id()),
43       to: vec![public()],
44       object,
45       cc: vec![community.followers_url.clone().into_inner()],
46       kind: AnnounceType::Announce,
47       id: generate_activity_id(
48         &AnnounceType::Announce,
49         &context.settings().get_protocol_and_hostname(),
50       )?,
51       unparsed: Default::default(),
52     };
53     let inboxes = list_community_follower_inboxes(community, additional_inboxes, context).await?;
54     send_lemmy_activity(context, &announce, &announce.id, community, inboxes, false).await
55   }
56 }
57
58 #[async_trait::async_trait(?Send)]
59 impl ActivityHandler for AnnounceActivity {
60   type DataType = LemmyContext;
61   async fn verify(
62     &self,
63     context: &Data<LemmyContext>,
64     request_counter: &mut i32,
65   ) -> Result<(), LemmyError> {
66     verify_is_public(&self.to)?;
67     verify_activity(self, &context.settings())?;
68     self.object.verify(context, request_counter).await?;
69     Ok(())
70   }
71
72   async fn receive(
73     self,
74     context: &Data<LemmyContext>,
75     request_counter: &mut i32,
76   ) -> Result<(), LemmyError> {
77     if is_activity_already_known(context.pool(), self.object.id_unchecked()).await? {
78       return Ok(());
79     }
80     insert_activity(
81       self.object.id_unchecked(),
82       self.object.clone(),
83       false,
84       true,
85       context.pool(),
86     )
87     .await?;
88     self.object.receive(context, request_counter).await
89   }
90 }