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