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