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