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