]> Untitled Git - lemmy.git/blob - crates/apub/src/activities/community/announce.rs
Merge logic for comment create and update
[lemmy.git] / crates / apub / src / activities / community / announce.rs
1 use crate::{
2   activities::{
3     comment::create_or_update::CreateOrUpdateComment,
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   CreateOrUpdateComment(CreateOrUpdateComment),
48   CreatePost(CreatePost),
49   UpdatePost(UpdatePost),
50   LikePostOrComment(LikePostOrComment),
51   DislikePostOrComment(DislikePostOrComment),
52   UndoLikePostOrComment(UndoLikePostOrComment),
53   UndoDislikePostOrComment(UndoDislikePostOrComment),
54   DeletePostCommentOrCommunity(DeletePostCommentOrCommunity),
55   UndoDeletePostCommentOrCommunity(UndoDeletePostCommentOrCommunity),
56   RemovePostCommentCommunityOrMod(RemovePostCommentCommunityOrMod),
57   UndoRemovePostCommentOrCommunity(UndoRemovePostCommentOrCommunity),
58   BlockUserFromCommunity(BlockUserFromCommunity),
59   UndoBlockUserFromCommunity(UndoBlockUserFromCommunity),
60   AddMod(AddMod),
61 }
62
63 #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
64 #[serde(rename_all = "camelCase")]
65 pub struct AnnounceActivity {
66   to: PublicUrl,
67   object: AnnouncableActivities,
68   cc: Vec<Url>,
69   #[serde(rename = "type")]
70   kind: AnnounceType,
71   #[serde(flatten)]
72   common: ActivityCommonFields,
73 }
74
75 impl AnnounceActivity {
76   pub async fn send(
77     object: AnnouncableActivities,
78     community: &Community,
79     additional_inboxes: Vec<Url>,
80     context: &LemmyContext,
81   ) -> Result<(), LemmyError> {
82     let announce = AnnounceActivity {
83       to: PublicUrl::Public,
84       object,
85       cc: vec![community.followers_url()],
86       kind: AnnounceType::Announce,
87       common: ActivityCommonFields {
88         context: lemmy_context(),
89         id: generate_activity_id(AnnounceType::Announce)?,
90         actor: community.actor_id(),
91         unparsed: Default::default(),
92       },
93     };
94     let inboxes = list_community_follower_inboxes(community, additional_inboxes, context).await?;
95     send_activity_new(
96       context,
97       &announce,
98       &announce.common.id,
99       community,
100       inboxes,
101       false,
102     )
103     .await
104   }
105 }
106
107 #[async_trait::async_trait(?Send)]
108 impl ActivityHandler for AnnounceActivity {
109   async fn verify(
110     &self,
111     context: &LemmyContext,
112     request_counter: &mut i32,
113   ) -> Result<(), LemmyError> {
114     verify_activity(self.common())?;
115     verify_community(&self.common.actor, context, request_counter).await?;
116     self.object.verify(context, request_counter).await?;
117     Ok(())
118   }
119
120   async fn receive(
121     &self,
122     context: &LemmyContext,
123     request_counter: &mut i32,
124   ) -> Result<(), LemmyError> {
125     if is_activity_already_known(context.pool(), self.object.common().id_unchecked()).await? {
126       return Ok(());
127     }
128     insert_activity(
129       self.object.common().id_unchecked(),
130       self.object.clone(),
131       false,
132       true,
133       context.pool(),
134     )
135     .await?;
136     self.object.receive(context, request_counter).await
137   }
138
139   fn common(&self) -> &ActivityCommonFields {
140     &self.common
141   }
142 }