]> Untitled Git - lemmy.git/blob - crates/api_crud/src/private_message/create.rs
6f099f79367e2aaa709e744e88239bffad6b849e
[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     check_person_block,
7     get_interface_language,
8     get_local_user_view_from_jwt,
9     local_site_to_slur_regex,
10     send_email_to_user,
11   },
12   websocket::{send::send_pm_ws_message, UserOperationCrud},
13   LemmyContext,
14 };
15 use lemmy_apub::{
16   generate_local_apub_endpoint,
17   protocol::activities::{
18     create_or_update::chat_message::CreateOrUpdateChatMessage,
19     CreateOrUpdateType,
20   },
21   EndpointType,
22 };
23 use lemmy_db_schema::{
24   source::{
25     local_site::LocalSite,
26     private_message::{PrivateMessage, PrivateMessageInsertForm, PrivateMessageUpdateForm},
27   },
28   traits::Crud,
29 };
30 use lemmy_db_views::structs::LocalUserView;
31 use lemmy_utils::{error::LemmyError, utils::remove_slurs, ConnectionId};
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 = LocalSite::read(context.pool()).await?;
47
48     let content_slurs_removed = remove_slurs(
49       &data.content.clone(),
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.clone())
57       .creator_id(local_user_view.person.id)
58       .recipient_id(data.recipient_id)
59       .build();
60
61     let inserted_private_message =
62       match PrivateMessage::create(context.pool(), &private_message_form).await {
63         Ok(private_message) => private_message,
64         Err(e) => {
65           return Err(LemmyError::from_error_message(
66             e,
67             "couldnt_create_private_message",
68           ));
69         }
70       };
71
72     let inserted_private_message_id = inserted_private_message.id;
73     let protocol_and_hostname = context.settings().get_protocol_and_hostname();
74     let apub_id = generate_local_apub_endpoint(
75       EndpointType::PrivateMessage,
76       &inserted_private_message_id.to_string(),
77       &protocol_and_hostname,
78     )?;
79     let updated_private_message = PrivateMessage::update(
80       context.pool(),
81       inserted_private_message.id,
82       &PrivateMessageUpdateForm::builder()
83         .ap_id(Some(apub_id))
84         .build(),
85     )
86     .await
87     .map_err(|e| LemmyError::from_error_message(e, "couldnt_create_private_message"))?;
88
89     CreateOrUpdateChatMessage::send(
90       updated_private_message.into(),
91       &local_user_view.person.into(),
92       CreateOrUpdateType::Create,
93       context,
94     )
95     .await?;
96
97     let res = send_pm_ws_message(
98       inserted_private_message.id,
99       UserOperationCrud::CreatePrivateMessage,
100       websocket_id,
101       context,
102     )
103     .await?;
104
105     // Send email to the local recipient, if one exists
106     if res.private_message_view.recipient.local {
107       let recipient_id = data.recipient_id;
108       let local_recipient = LocalUserView::read_person(context.pool(), recipient_id).await?;
109       let lang = get_interface_language(&local_recipient);
110       let inbox_link = format!("{}/inbox", context.settings().get_protocol_and_hostname());
111       send_email_to_user(
112         &local_recipient,
113         &lang.notification_private_message_subject(&local_recipient.person.name),
114         &lang.notification_private_message_body(
115           &inbox_link,
116           &content_slurs_removed,
117           &local_recipient.person.name,
118         ),
119         context.settings(),
120       );
121     }
122
123     Ok(res)
124   }
125 }