3 comment::create_or_update::CreateOrUpdateComment,
6 block_user::BlockUserFromCommunity,
7 list_community_follower_inboxes,
9 undo_block_user::UndoBlockUserFromCommunity,
10 update::UpdateCommunity,
12 deletion::{delete::Delete, undo_delete::UndoDelete},
14 post::create_or_update::CreateOrUpdatePost,
18 voting::{undo_vote::UndoVote, vote::Vote},
20 fetcher::object_id::ObjectId,
21 http::is_activity_already_known,
23 objects::community::ApubCommunity,
25 use activitystreams::{activity::kind::AnnounceType, public, unparsed::Unparsed};
28 traits::{ActivityFields, ActivityHandler, ActorType},
29 verify::verify_urls_match,
31 use lemmy_utils::LemmyError;
32 use lemmy_websocket::LemmyContext;
33 use serde::{Deserialize, Serialize};
36 #[derive(Clone, Debug, Deserialize, Serialize, ActivityHandler, ActivityFields)]
38 #[activity_handler(LemmyContext)]
39 pub enum AnnouncableActivities {
40 CreateOrUpdateComment(CreateOrUpdateComment),
41 CreateOrUpdatePost(Box<CreateOrUpdatePost>),
45 UndoDelete(UndoDelete),
46 UpdateCommunity(Box<UpdateCommunity>),
47 BlockUserFromCommunity(BlockUserFromCommunity),
48 UndoBlockUserFromCommunity(UndoBlockUserFromCommunity),
53 #[async_trait::async_trait(?Send)]
54 pub(crate) trait GetCommunity {
55 async fn get_community(
57 context: &LemmyContext,
58 request_counter: &mut i32,
59 ) -> Result<ApubCommunity, LemmyError>;
62 #[async_trait::async_trait(?Send)]
63 impl GetCommunity for AnnouncableActivities {
64 async fn get_community(
66 context: &LemmyContext,
67 request_counter: &mut i32,
68 ) -> Result<ApubCommunity, LemmyError> {
69 use AnnouncableActivities::*;
70 let community = match self {
71 CreateOrUpdateComment(a) => a.get_community(context, request_counter).await?,
72 CreateOrUpdatePost(a) => a.get_community(context, request_counter).await?,
73 Vote(a) => a.get_community(context, request_counter).await?,
74 UndoVote(a) => a.get_community(context, request_counter).await?,
75 Delete(a) => a.get_community(context, request_counter).await?,
76 UndoDelete(a) => a.get_community(context, request_counter).await?,
77 UpdateCommunity(a) => a.get_community(context, request_counter).await?,
78 BlockUserFromCommunity(a) => a.get_community(context, request_counter).await?,
79 UndoBlockUserFromCommunity(a) => a.get_community(context, request_counter).await?,
80 AddMod(a) => a.get_community(context, request_counter).await?,
81 RemoveMod(a) => a.get_community(context, request_counter).await?,
83 verify_urls_match(self.actor(), &community.actor_id())?;
88 #[derive(Clone, Debug, Deserialize, Serialize, ActivityFields)]
89 #[serde(rename_all = "camelCase")]
90 pub struct AnnounceActivity {
91 actor: ObjectId<ApubCommunity>,
93 object: AnnouncableActivities,
95 #[serde(rename = "type")]
102 impl AnnounceActivity {
104 object: AnnouncableActivities,
105 community: &ApubCommunity,
106 additional_inboxes: Vec<Url>,
107 context: &LemmyContext,
108 ) -> Result<(), LemmyError> {
109 let announce = AnnounceActivity {
110 actor: ObjectId::new(community.actor_id()),
113 cc: vec![community.followers_url.clone().into_inner()],
114 kind: AnnounceType::Announce,
115 id: generate_activity_id(
116 &AnnounceType::Announce,
117 &context.settings().get_protocol_and_hostname(),
119 unparsed: Default::default(),
121 let inboxes = list_community_follower_inboxes(community, additional_inboxes, context).await?;
122 send_lemmy_activity(context, &announce, &announce.id, community, inboxes, false).await
126 #[async_trait::async_trait(?Send)]
127 impl ActivityHandler for AnnounceActivity {
128 type DataType = LemmyContext;
131 context: &Data<LemmyContext>,
132 request_counter: &mut i32,
133 ) -> Result<(), LemmyError> {
134 verify_is_public(&self.to)?;
135 verify_activity(self, &context.settings())?;
136 self.object.verify(context, request_counter).await?;
142 context: &Data<LemmyContext>,
143 request_counter: &mut i32,
144 ) -> Result<(), LemmyError> {
145 if is_activity_already_known(context.pool(), self.object.id_unchecked()).await? {
149 self.object.id_unchecked(),
156 self.object.receive(context, request_counter).await