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