]> Untitled Git - lemmy.git/blob - crates/apub/src/activities/private_message/create_or_update.rs
09582689be35f189b54a0b03292ce04efa2fd35a
[lemmy.git] / crates / apub / src / activities / private_message / create_or_update.rs
1 use crate::{
2   activities::{
3     generate_activity_id,
4     private_message::send_websocket_message,
5     verify_activity,
6     verify_person,
7     CreateOrUpdateType,
8   },
9   activity_queue::send_activity_new,
10   extensions::context::lemmy_context,
11   objects::{private_message::Note, FromApub, ToApub},
12   ActorType,
13 };
14 use lemmy_api_common::blocking;
15 use lemmy_apub_lib::{verify_domains_match, ActivityCommonFields, ActivityHandler};
16 use lemmy_db_queries::Crud;
17 use lemmy_db_schema::source::{person::Person, private_message::PrivateMessage};
18 use lemmy_utils::LemmyError;
19 use lemmy_websocket::{LemmyContext, UserOperationCrud};
20 use url::Url;
21
22 #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
23 #[serde(rename_all = "camelCase")]
24 pub struct CreateOrUpdatePrivateMessage {
25   to: Url,
26   object: Note,
27   #[serde(rename = "type")]
28   kind: CreateOrUpdateType,
29   #[serde(flatten)]
30   common: ActivityCommonFields,
31 }
32
33 impl CreateOrUpdatePrivateMessage {
34   pub async fn send(
35     private_message: &PrivateMessage,
36     actor: &Person,
37     kind: CreateOrUpdateType,
38     context: &LemmyContext,
39   ) -> Result<(), LemmyError> {
40     let recipient_id = private_message.recipient_id;
41     let recipient =
42       blocking(context.pool(), move |conn| Person::read(conn, recipient_id)).await??;
43
44     let id = generate_activity_id(kind.clone())?;
45     let create_or_update = CreateOrUpdatePrivateMessage {
46       to: recipient.actor_id(),
47       object: private_message.to_apub(context.pool()).await?,
48       kind,
49       common: ActivityCommonFields {
50         context: lemmy_context(),
51         id: id.clone(),
52         actor: actor.actor_id(),
53         unparsed: Default::default(),
54       },
55     };
56     let inbox = vec![recipient.get_shared_inbox_or_inbox_url()];
57     send_activity_new(context, &create_or_update, &id, actor, inbox, true).await
58   }
59 }
60 #[async_trait::async_trait(?Send)]
61 impl ActivityHandler for CreateOrUpdatePrivateMessage {
62   async fn verify(
63     &self,
64     context: &LemmyContext,
65     request_counter: &mut i32,
66   ) -> Result<(), LemmyError> {
67     verify_activity(self.common())?;
68     verify_person(&self.common.actor, context, request_counter).await?;
69     verify_domains_match(&self.common.actor, self.object.id_unchecked())?;
70     self.object.verify(context, request_counter).await?;
71     Ok(())
72   }
73
74   async fn receive(
75     self,
76     context: &LemmyContext,
77     request_counter: &mut i32,
78   ) -> Result<(), LemmyError> {
79     let private_message =
80       PrivateMessage::from_apub(&self.object, context, &self.common.actor, request_counter).await?;
81
82     let notif_type = match self.kind {
83       CreateOrUpdateType::Create => UserOperationCrud::CreatePrivateMessage,
84       CreateOrUpdateType::Update => UserOperationCrud::EditPrivateMessage,
85     };
86     send_websocket_message(private_message.id, notif_type, context).await?;
87
88     Ok(())
89   }
90
91   fn common(&self) -> &ActivityCommonFields {
92     &self.common
93   }
94 }