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