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