Skip to content

Commit c550c72

Browse files
committed
refactor(messages): internals messages are now stored in database and are shown on panel
1 parent b3e5756 commit c550c72

7 files changed

Lines changed: 116 additions & 12 deletions

File tree

rustmail/src/api/handler/bot/tickets.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ pub struct ThreadMessage {
2222
pub message_number: Option<i64>,
2323
pub created_at: String,
2424
pub content: String,
25+
pub is_internal: bool,
2526
}
2627

2728
#[derive(Debug, Clone, Serialize)]
@@ -180,7 +181,8 @@ pub async fn handle_tickets_bot(
180181
inbox_message_id,
181182
message_number,
182183
created_at as "created_at: String",
183-
content
184+
content,
185+
is_internal
184186
FROM thread_messages
185187
WHERE thread_id = ?
186188
ORDER BY created_at ASC
@@ -210,6 +212,7 @@ pub async fn handle_tickets_bot(
210212
message_number: m.message_number,
211213
created_at: m.created_at,
212214
content: m.content,
215+
is_internal: m.is_internal,
213216
})
214217
.collect();
215218

@@ -391,7 +394,8 @@ pub async fn handle_tickets_bot(
391394
inbox_message_id,
392395
message_number,
393396
created_at,
394-
content
397+
content,
398+
is_internal
395399
FROM thread_messages
396400
WHERE thread_id IN ({})
397401
ORDER BY thread_id, created_at ASC
@@ -412,6 +416,7 @@ pub async fn handle_tickets_bot(
412416
Option<i64>,
413417
String,
414418
String,
419+
bool,
415420
),
416421
>(&messages_query_str);
417422

@@ -445,6 +450,7 @@ pub async fn handle_tickets_bot(
445450
message_number: msg.7,
446451
created_at: msg.8,
447452
content: msg.9,
453+
is_internal: msg.10,
448454
});
449455
}
450456

rustmail/src/db/operations/messages.rs

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ pub async fn get_latest_thread_message(
166166
r#"
167167
SELECT id, thread_id, user_id, user_name, is_anonymous,
168168
dm_message_id, inbox_message_id, message_number,
169-
created_at as "created_at: String", content
169+
created_at as "created_at: String", content, is_internal
170170
FROM thread_messages
171171
WHERE thread_id = ?
172172
ORDER BY created_at DESC
@@ -188,6 +188,7 @@ pub async fn get_latest_thread_message(
188188
message_number: row.message_number,
189189
_created_at: row.created_at,
190190
content: row.content,
191+
_is_internal: row.is_internal,
191192
});
192193

193194
Ok(latest)
@@ -259,6 +260,49 @@ pub async fn insert_user_message_with_ids(
259260
Ok(())
260261
}
261262

263+
pub async fn insert_internal_message(
264+
ctx: &Context,
265+
msg: &Message,
266+
thread_id: &str,
267+
pool: &SqlitePool,
268+
config: &Config,
269+
) -> Result<(), Error> {
270+
let user_id = msg.author.id.get() as i64;
271+
let inbox_message_id = msg.id.to_string();
272+
273+
let user_name = msg
274+
.author
275+
.id
276+
.to_user(&ctx.http)
277+
.await
278+
.map(|user| user.name)
279+
.unwrap_or_else(|_| "Unknown".to_string());
280+
281+
let content = extract_message_content(msg, config);
282+
283+
sqlx::query!(
284+
r#"
285+
INSERT INTO thread_messages (
286+
thread_id, user_id, user_name, is_anonymous, inbox_message_id, content, thread_status, is_internal
287+
) VALUES (
288+
?, ?, ?, ?, ?, ?, ?, ?
289+
)
290+
"#,
291+
thread_id,
292+
user_id,
293+
user_name,
294+
false,
295+
inbox_message_id,
296+
content,
297+
1,
298+
true
299+
)
300+
.execute(pool)
301+
.await?;
302+
303+
Ok(())
304+
}
305+
262306
pub async fn get_thread_message_by_inbox_message_id(
263307
inbox_message_id: &str,
264308
pool: &SqlitePool,
@@ -267,7 +311,7 @@ pub async fn get_thread_message_by_inbox_message_id(
267311
r#"
268312
SELECT id, thread_id, user_id, user_name, is_anonymous,
269313
dm_message_id, inbox_message_id, message_number,
270-
created_at as "created_at: String", content
314+
created_at as "created_at: String", content, is_internal
271315
FROM thread_messages
272316
WHERE inbox_message_id = ?
273317
ORDER BY created_at DESC
@@ -289,6 +333,7 @@ pub async fn get_thread_message_by_inbox_message_id(
289333
message_number: row.message_number,
290334
_created_at: row.created_at,
291335
content: row.content,
336+
_is_internal: row.is_internal,
292337
}) {
293338
Some(row) => row,
294339
None => {
@@ -309,7 +354,7 @@ pub async fn get_thread_message_by_message_id(
309354
r#"
310355
SELECT id, thread_id, user_id, user_name, is_anonymous,
311356
dm_message_id, inbox_message_id, message_number,
312-
created_at as "created_at: String", content
357+
created_at as "created_at: String", content, is_internal
313358
FROM thread_messages
314359
WHERE dm_message_id = ? OR inbox_message_id = ?
315360
ORDER BY created_at DESC
@@ -332,6 +377,7 @@ pub async fn get_thread_message_by_message_id(
332377
message_number: row.message_number,
333378
_created_at: row.created_at,
334379
content: row.content,
380+
_is_internal: row.is_internal,
335381
}) {
336382
Some(row) => row,
337383
None => {
@@ -354,7 +400,7 @@ pub async fn get_thread_message_by_dm_message_id(
354400
r#"
355401
SELECT id, thread_id, user_id, user_name, is_anonymous,
356402
dm_message_id, inbox_message_id, message_number,
357-
created_at as "created_at: String", content
403+
created_at as "created_at: String", content, is_internal
358404
FROM thread_messages
359405
WHERE dm_message_id = ?
360406
AND thread_status = 1
@@ -377,6 +423,7 @@ pub async fn get_thread_message_by_dm_message_id(
377423
message_number: row.message_number,
378424
_created_at: row.created_at,
379425
content: row.content,
426+
_is_internal: row.is_internal,
380427
}) {
381428
Some(row) => row,
382429
None => {
@@ -401,4 +448,5 @@ pub struct ThreadMessage {
401448
pub message_number: Option<i64>,
402449
pub _created_at: String,
403450
pub content: String,
451+
pub _is_internal: bool,
404452
}

rustmail/src/handlers/guild_messages_handler.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,23 @@ impl EventHandler for GuildMessagesHandler {
242242
}
243243
return;
244244
}
245+
246+
if let Some(guild_id) = msg.guild_id {
247+
let staff_guild_id = self.config.bot.get_staff_guild_id();
248+
if guild_id.get() == staff_guild_id && !msg.author.bot {
249+
if let Some(pool) = &self.config.db_pool {
250+
let channel_id_str = msg.channel_id.to_string();
251+
if let Some(_thread) = get_thread_by_channel_id(&channel_id_str, pool).await {
252+
if let Err(e) =
253+
insert_internal_message(&ctx, &msg, &_thread.id, pool, &self.config)
254+
.await
255+
{
256+
eprintln!("Failed to record internal message: {}", e);
257+
}
258+
}
259+
}
260+
}
261+
}
245262
return;
246263
}
247264

rustmail/src/utils/message/message_builder.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -775,7 +775,7 @@ impl<'a> StaffReply<'a> {
775775
.add_attachments(self.attachments.clone())
776776
.to_channel(thread_channel);
777777

778-
let thread_msg = thread_builder.send(true).await?;
778+
let thread_msg = thread_builder.send(false).await?;
779779

780780
let dm_msg_opt: Option<Message> = self.build_and_send_message(top_role_name).await;
781781

@@ -927,7 +927,8 @@ impl<'a> UserIncoming<'a> {
927927
.content(self.content)
928928
.add_attachments(self.attachments)
929929
.to_channel(thread_channel);
930-
let sent = builder.send(true).await?;
930+
931+
let sent = builder.send(false).await?;
931932
if let Err(e) = insert_user_message_with_ids(
932933
self.dm_msg,
933934
&sent,

rustmail_panel/src/components/ticket.rs

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,19 @@ pub struct ThreadMessage {
2323
pub message_number: Option<i64>,
2424
pub created_at: String,
2525
pub content: String,
26+
pub is_internal: bool,
2627
}
2728

2829
impl ThreadMessage {
2930
fn message_type(&self) -> MessageType {
30-
if self.user_name.starts_with("System") || self.user_name == "System" {
31-
MessageType::System
32-
} else if self.user_id == 0 || self.is_anonymous {
31+
if self.is_internal {
32+
MessageType::Internal
33+
} else if self.message_number.is_some() {
34+
MessageType::Staff
35+
} else if self.dm_message_id.is_some() && self.inbox_message_id.is_some() {
3336
MessageType::User
3437
} else {
35-
MessageType::Staff
38+
MessageType::System
3639
}
3740
}
3841
}
@@ -42,6 +45,7 @@ enum MessageType {
4245
User,
4346
Staff,
4447
System,
48+
Internal,
4549
}
4650

4751
#[derive(Clone, PartialEq, Deserialize, Debug)]
@@ -507,6 +511,7 @@ pub fn ticket_details(props: &TicketDetailsProps) -> Html {
507511
let show_user = use_state(|| true);
508512
let show_staff = use_state(|| true);
509513
let show_system = use_state(|| true);
514+
let show_internal = use_state(|| true);
510515
let search_query = use_state(|| String::new());
511516

512517
let permissions = use_state(|| None::<Vec<PanelPermission>>);
@@ -594,6 +599,7 @@ pub fn ticket_details(props: &TicketDetailsProps) -> Html {
594599
MessageType::User => *show_user,
595600
MessageType::Staff => *show_staff,
596601
MessageType::System => *show_system,
602+
MessageType::Internal => *show_internal,
597603
};
598604

599605
let search_match = if search_query.is_empty() {
@@ -746,6 +752,25 @@ pub fn ticket_details(props: &TicketDetailsProps) -> Html {
746752
<i class="bi bi-gear"></i>
747753
{i18n.t("panel.tickets.filter_system")}
748754
</button>
755+
756+
<button
757+
onclick={{
758+
let show_internal = show_internal.clone();
759+
move |_| show_internal.set(!*show_internal)
760+
}}
761+
class={classes!(
762+
"px-4", "py-2", "rounded-lg", "border", "transition-all", "text-sm", "font-medium",
763+
"flex", "items-center", "gap-2",
764+
if *show_internal {
765+
"bg-purple-500/20 text-purple-400 border-purple-500/50"
766+
} else {
767+
"bg-slate-700/30 text-gray-400 border-slate-600"
768+
}
769+
)}
770+
>
771+
<i class="bi bi-pencil-square"></i>
772+
{i18n.t("panel.tickets.filter_internal")}
773+
</button>
749774
</div>
750775
</div>
751776

@@ -779,6 +804,11 @@ pub fn ticket_details(props: &TicketDetailsProps) -> Html {
779804
"border-yellow-500/30",
780805
"text-yellow-400"
781806
),
807+
MessageType::Internal => (
808+
"bg-purple-500/10",
809+
"border-purple-500/30",
810+
"text-purple-400"
811+
),
782812
};
783813

784814
html! {

rustmail_panel/src/i18n/en/en.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@
168168
"filter_user": "Users",
169169
"filter_staff": "Staff",
170170
"filter_system": "System",
171+
"filter_internal": "Internal",
171172
"tickets_per_page": "Tickets per page",
172173
"no_messages": "No messages to display with selected filters"
173174
},

rustmail_panel/src/i18n/fr/fr.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@
168168
"filter_user": "Utilisateurs",
169169
"filter_staff": "Staff",
170170
"filter_system": "Système",
171+
"filter_internal": "Interne",
171172
"no_messages": "Aucun message à afficher avec les filtres sélectionnés",
172173
"tickets_per_page": "Tickets par page"
173174
},

0 commit comments

Comments
 (0)