]> Untitled Git - lemmy.git/blob - crates/api_crud/src/private_message/create.rs
03d994c08b79e578d0c5a5223d8b66ea78fc7886
[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   generate_local_apub_endpoint,
5   private_message::{CreatePrivateMessage, PrivateMessageResponse},
6   utils::{
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   websocket::{send::send_pm_ws_message, UserOperationCrud},
14   EndpointType,
15   LemmyContext,
16 };
17 use lemmy_apub::protocol::activities::{
18   create_or_update::chat_message::CreateOrUpdateChatMessage,
19   CreateOrUpdateType,
20 };
21 use lemmy_db_schema::{
22   source::{
23     local_site::LocalSite,
24     private_message::{PrivateMessage, PrivateMessageInsertForm, PrivateMessageUpdateForm},
25   },
26   traits::Crud,
27 };
28 use lemmy_db_views::structs::LocalUserView;
29 use lemmy_utils::{error::LemmyError, utils::remove_slurs, ConnectionId};
30
31 #[async_trait::async_trait(?Send)]
32 impl PerformCrud for CreatePrivateMessage {
33   type Response = PrivateMessageResponse;
34
35   #[tracing::instrument(skip(self, context, websocket_id))]
36   async fn perform(
37     &self,
38     context: &Data<LemmyContext>,
39     websocket_id: Option<ConnectionId>,
40   ) -> Result<PrivateMessageResponse, LemmyError> {
41     let data: &CreatePrivateMessage = self;
42     let local_user_view =
43       get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
44     let local_site = LocalSite::read(context.pool()).await?;
45
46     let content_slurs_removed = remove_slurs(
47       &data.content.clone(),
48       &local_site_to_slur_regex(&local_site),
49     );
50
51     check_person_block(local_user_view.person.id, data.recipient_id, context.pool()).await?;
52
53     let private_message_form = PrivateMessageInsertForm::builder()
54       .content(content_slurs_removed.clone())
55       .creator_id(local_user_view.person.id)
56       .recipient_id(data.recipient_id)
57       .build();
58
59     let inserted_private_message =
60       match PrivateMessage::create(context.pool(), &private_message_form).await {
61         Ok(private_message) => private_message,
62         Err(e) => {
63           return Err(LemmyError::from_error_message(
64             e,
65             "couldnt_create_private_message",
66           ));
67         }
68       };
69
70     let inserted_private_message_id = inserted_private_message.id;
71     let protocol_and_hostname = context.settings().get_protocol_and_hostname();
72     let apub_id = generate_local_apub_endpoint(
73       EndpointType::PrivateMessage,
74       &inserted_private_message_id.to_string(),
75       &protocol_and_hostname,
76     )?;
77     let updated_private_message = PrivateMessage::update(
78       context.pool(),
79       inserted_private_message.id,
80       &PrivateMessageUpdateForm::builder()
81         .ap_id(Some(apub_id))
82         .build(),
83     )
84     .await
85     .map_err(|e| LemmyError::from_error_message(e, "couldnt_create_private_message"))?;
86
87     CreateOrUpdateChatMessage::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 = LocalUserView::read_person(context.pool(), recipient_id).await?;
107       let lang = get_interface_language(&local_recipient);
108       let inbox_link = format!("{}/inbox", context.settings().get_protocol_and_hostname());
109       send_email_to_user(
110         &local_recipient,
111         &lang.notification_private_message_subject(&local_recipient.person.name),
112         &lang.notification_private_message_body(
113           &inbox_link,
114           &content_slurs_removed,
115           &local_recipient.person.name,
116         ),
117         context.settings(),
118       );
119     }
120
121     Ok(res)
122   }
123 }