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