]> Untitled Git - lemmy.git/blob - crates/api_crud/src/private_message/create.rs
Merge different delete activities for better compatibility (fixes #2066) (#2073)
[lemmy.git] / crates / api_crud / src / private_message / create.rs
1 use crate::PerformCrud;
2 use actix_web::web::Data;
3 use lemmy_api_common::{
4   blocking,
5   check_person_block,
6   get_local_user_view_from_jwt,
7   person::{CreatePrivateMessage, PrivateMessageResponse},
8   send_email_to_user,
9 };
10 use lemmy_apub::{
11   generate_local_apub_endpoint,
12   protocol::activities::{
13     create_or_update::private_message::CreateOrUpdatePrivateMessage,
14     CreateOrUpdateType,
15   },
16   EndpointType,
17 };
18 use lemmy_db_schema::{
19   source::private_message::{PrivateMessage, PrivateMessageForm},
20   traits::Crud,
21 };
22 use lemmy_db_views::local_user_view::LocalUserView;
23 use lemmy_utils::{utils::remove_slurs, ConnectionId, LemmyError};
24 use lemmy_websocket::{send::send_pm_ws_message, LemmyContext, UserOperationCrud};
25
26 #[async_trait::async_trait(?Send)]
27 impl PerformCrud for CreatePrivateMessage {
28   type Response = PrivateMessageResponse;
29
30   #[tracing::instrument(skip(self, context, websocket_id))]
31   async fn perform(
32     &self,
33     context: &Data<LemmyContext>,
34     websocket_id: Option<ConnectionId>,
35   ) -> Result<PrivateMessageResponse, LemmyError> {
36     let data: &CreatePrivateMessage = self;
37     let local_user_view =
38       get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
39
40     let content_slurs_removed =
41       remove_slurs(&data.content.to_owned(), &context.settings().slur_regex());
42
43     check_person_block(local_user_view.person.id, data.recipient_id, context.pool()).await?;
44
45     let private_message_form = PrivateMessageForm {
46       content: content_slurs_removed.to_owned(),
47       creator_id: local_user_view.person.id,
48       recipient_id: data.recipient_id,
49       ..PrivateMessageForm::default()
50     };
51
52     let inserted_private_message = match blocking(context.pool(), move |conn| {
53       PrivateMessage::create(conn, &private_message_form)
54     })
55     .await?
56     {
57       Ok(private_message) => private_message,
58       Err(e) => {
59         return Err(LemmyError::from(e).with_message("couldnt_create_private_message"));
60       }
61     };
62
63     let inserted_private_message_id = inserted_private_message.id;
64     let protocol_and_hostname = context.settings().get_protocol_and_hostname();
65     let updated_private_message = blocking(
66       context.pool(),
67       move |conn| -> Result<PrivateMessage, LemmyError> {
68         let apub_id = generate_local_apub_endpoint(
69           EndpointType::PrivateMessage,
70           &inserted_private_message_id.to_string(),
71           &protocol_and_hostname,
72         )?;
73         Ok(PrivateMessage::update_ap_id(
74           conn,
75           inserted_private_message_id,
76           apub_id,
77         )?)
78       },
79     )
80     .await?
81     .map_err(LemmyError::from)
82     .map_err(|e| e.with_message("couldnt_create_private_message"))?;
83
84     CreateOrUpdatePrivateMessage::send(
85       updated_private_message.into(),
86       &local_user_view.person.into(),
87       CreateOrUpdateType::Create,
88       context,
89     )
90     .await?;
91
92     let res = send_pm_ws_message(
93       inserted_private_message.id,
94       UserOperationCrud::CreatePrivateMessage,
95       websocket_id,
96       context,
97     )
98     .await?;
99
100     // Send email to the local recipient, if one exists
101     if res.private_message_view.recipient.local {
102       let recipient_id = data.recipient_id;
103       let local_recipient = blocking(context.pool(), move |conn| {
104         LocalUserView::read_person(conn, recipient_id)
105       })
106       .await??;
107       send_email_to_user(
108         &local_recipient,
109         "Private Message from",
110         "Private Message",
111         &content_slurs_removed,
112         &context.settings(),
113       );
114     }
115
116     Ok(res)
117   }
118 }