]> Untitled Git - lemmy.git/blob - crates/apub/src/activities/community/announce.rs
Add docs for MediaType, PublicUrl values
[lemmy.git] / crates / apub / src / activities / community / announce.rs
1 use crate::{
2   activities::{
3     comment::{create::CreateComment, update::UpdateComment},
4     community::{
5       add_mod::AddMod,
6       block_user::BlockUserFromCommunity,
7       list_community_follower_inboxes,
8       undo_block_user::UndoBlockUserFromCommunity,
9     },
10     deletion::{
11       delete::DeletePostCommentOrCommunity,
12       undo_delete::UndoDeletePostCommentOrCommunity,
13     },
14     generate_activity_id,
15     post::{create::CreatePost, update::UpdatePost},
16     removal::{
17       remove::RemovePostCommentCommunityOrMod,
18       undo_remove::UndoRemovePostCommentOrCommunity,
19     },
20     verify_activity,
21     verify_community,
22     voting::{
23       dislike::DislikePostOrComment,
24       like::LikePostOrComment,
25       undo_dislike::UndoDislikePostOrComment,
26       undo_like::UndoLikePostOrComment,
27     },
28   },
29   activity_queue::send_activity_new,
30   extensions::context::lemmy_context,
31   http::is_activity_already_known,
32   insert_activity,
33   ActorType,
34   CommunityType,
35 };
36 use activitystreams::activity::kind::AnnounceType;
37 use lemmy_apub_lib::{values::PublicUrl, ActivityCommonFields, ActivityHandler};
38 use lemmy_db_schema::source::community::Community;
39 use lemmy_utils::LemmyError;
40 use lemmy_websocket::LemmyContext;
41 use serde::{Deserialize, Serialize};
42 use url::Url;
43
44 #[derive(Clone, Debug, Deserialize, Serialize, ActivityHandler)]
45 #[serde(untagged)]
46 pub enum AnnouncableActivities {
47   CreateComment(CreateComment),
48   UpdateComment(UpdateComment),
49   CreatePost(CreatePost),
50   UpdatePost(UpdatePost),
51   LikePostOrComment(LikePostOrComment),
52   DislikePostOrComment(DislikePostOrComment),
53   UndoLikePostOrComment(UndoLikePostOrComment),
54   UndoDislikePostOrComment(UndoDislikePostOrComment),
55   DeletePostCommentOrCommunity(DeletePostCommentOrCommunity),
56   UndoDeletePostCommentOrCommunity(UndoDeletePostCommentOrCommunity),
57   RemovePostCommentCommunityOrMod(RemovePostCommentCommunityOrMod),
58   UndoRemovePostCommentOrCommunity(UndoRemovePostCommentOrCommunity),
59   BlockUserFromCommunity(BlockUserFromCommunity),
60   UndoBlockUserFromCommunity(UndoBlockUserFromCommunity),
61   AddMod(AddMod),
62 }
63
64 #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
65 #[serde(rename_all = "camelCase")]
66 pub struct AnnounceActivity {
67   to: PublicUrl,
68   object: AnnouncableActivities,
69   cc: Vec<Url>,
70   #[serde(rename = "type")]
71   kind: AnnounceType,
72   #[serde(flatten)]
73   common: ActivityCommonFields,
74 }
75
76 impl AnnounceActivity {
77   pub async fn send(
78     object: AnnouncableActivities,
79     community: &Community,
80     additional_inboxes: Vec<Url>,
81     context: &LemmyContext,
82   ) -> Result<(), LemmyError> {
83     let announce = AnnounceActivity {
84       to: PublicUrl::Public,
85       object,
86       cc: vec![community.followers_url()],
87       kind: AnnounceType::Announce,
88       common: ActivityCommonFields {
89         context: lemmy_context(),
90         id: generate_activity_id(AnnounceType::Announce)?,
91         actor: community.actor_id(),
92         unparsed: Default::default(),
93       },
94     };
95     let inboxes = list_community_follower_inboxes(community, additional_inboxes, context).await?;
96     send_activity_new(
97       context,
98       &announce,
99       &announce.common.id,
100       community,
101       inboxes,
102       false,
103     )
104     .await
105   }
106 }
107
108 #[async_trait::async_trait(?Send)]
109 impl ActivityHandler for AnnounceActivity {
110   async fn verify(
111     &self,
112     context: &LemmyContext,
113     request_counter: &mut i32,
114   ) -> Result<(), LemmyError> {
115     verify_activity(self.common())?;
116     verify_community(&self.common.actor, context, request_counter).await?;
117     self.object.verify(context, request_counter).await?;
118     Ok(())
119   }
120
121   async fn receive(
122     &self,
123     context: &LemmyContext,
124     request_counter: &mut i32,
125   ) -> Result<(), LemmyError> {
126     if is_activity_already_known(context.pool(), self.object.common().id_unchecked()).await? {
127       return Ok(());
128     }
129     insert_activity(
130       self.object.common().id_unchecked(),
131       self.object.clone(),
132       false,
133       true,
134       context.pool(),
135     )
136     .await?;
137     self.object.receive(context, request_counter).await
138   }
139
140   fn common(&self) -> &ActivityCommonFields {
141     &self.common
142   }
143 }