]> Untitled Git - lemmy.git/blob - crates/apub/src/activities/create_or_update/private_message.rs
Merge websocket crate into api_common
[lemmy.git] / crates / apub / src / activities / create_or_update / private_message.rs
1 use crate::{
2   activities::{generate_activity_id, send_lemmy_activity, verify_person},
3   objects::{person::ApubPerson, private_message::ApubPrivateMessage},
4   protocol::activities::{
5     create_or_update::chat_message::CreateOrUpdateChatMessage,
6     CreateOrUpdateType,
7   },
8   ActorType,
9 };
10 use activitypub_federation::{
11   core::object_id::ObjectId,
12   data::Data,
13   traits::{ActivityHandler, Actor, ApubObject},
14   utils::verify_domains_match,
15 };
16 use lemmy_api_common::{
17   websocket::{send::send_pm_ws_message, UserOperationCrud},
18   LemmyContext,
19 };
20 use lemmy_db_schema::{source::person::Person, traits::Crud};
21 use lemmy_utils::error::LemmyError;
22 use url::Url;
23
24 impl CreateOrUpdateChatMessage {
25   #[tracing::instrument(skip_all)]
26   pub async fn send(
27     private_message: ApubPrivateMessage,
28     actor: &ApubPerson,
29     kind: CreateOrUpdateType,
30     context: &LemmyContext,
31   ) -> Result<(), LemmyError> {
32     let recipient_id = private_message.recipient_id;
33     let recipient: ApubPerson = Person::read(context.pool(), recipient_id).await?.into();
34
35     let id = generate_activity_id(
36       kind.clone(),
37       &context.settings().get_protocol_and_hostname(),
38     )?;
39     let create_or_update = CreateOrUpdateChatMessage {
40       id: id.clone(),
41       actor: ObjectId::new(actor.actor_id()),
42       to: [ObjectId::new(recipient.actor_id())],
43       object: private_message.into_apub(context).await?,
44       kind,
45     };
46     let inbox = vec![recipient.shared_inbox_or_inbox()];
47     send_lemmy_activity(context, create_or_update, actor, inbox, true).await
48   }
49 }
50
51 #[async_trait::async_trait(?Send)]
52 impl ActivityHandler for CreateOrUpdateChatMessage {
53   type DataType = LemmyContext;
54   type Error = LemmyError;
55
56   fn id(&self) -> &Url {
57     &self.id
58   }
59
60   fn actor(&self) -> &Url {
61     self.actor.inner()
62   }
63
64   #[tracing::instrument(skip_all)]
65   async fn verify(
66     &self,
67     context: &Data<LemmyContext>,
68     request_counter: &mut i32,
69   ) -> Result<(), LemmyError> {
70     verify_person(&self.actor, context, request_counter).await?;
71     verify_domains_match(self.actor.inner(), self.object.id.inner())?;
72     verify_domains_match(self.to[0].inner(), self.object.to[0].inner())?;
73     ApubPrivateMessage::verify(&self.object, self.actor.inner(), context, request_counter).await?;
74     Ok(())
75   }
76
77   #[tracing::instrument(skip_all)]
78   async fn receive(
79     self,
80     context: &Data<LemmyContext>,
81     request_counter: &mut i32,
82   ) -> Result<(), LemmyError> {
83     let private_message =
84       ApubPrivateMessage::from_apub(self.object, context, request_counter).await?;
85
86     let notif_type = match self.kind {
87       CreateOrUpdateType::Create => UserOperationCrud::CreatePrivateMessage,
88       CreateOrUpdateType::Update => UserOperationCrud::EditPrivateMessage,
89     };
90     send_pm_ws_message(private_message.id, notif_type, None, context).await?;
91
92     Ok(())
93   }
94 }