From e472936c51a1f43196551a711c8bfa1f5f59841c Mon Sep 17 00:00:00 2001 From: Rafael Bradley Date: Fri, 15 Aug 2025 01:43:36 -0300 Subject: [PATCH] Add support for deleting messages on call --- src/database/models.rs | 12 +++---- src/groups/calls/events.rs | 69 ++++++++++++++++++++++++++++++++++++-- src/main.rs | 3 +- 3 files changed, 73 insertions(+), 11 deletions(-) diff --git a/src/database/models.rs b/src/database/models.rs index e5f44c9..1d2845f 100644 --- a/src/database/models.rs +++ b/src/database/models.rs @@ -939,7 +939,6 @@ pub struct MessageBuilder { message: Option, profile: Option, call_id: Option, - is_deleted: bool, is_censored: bool, propagation_message_id: Option, propagation_channel_id: Option, @@ -952,7 +951,6 @@ impl MessageBuilder { message: None, profile: None, call_id: None, - is_deleted: false, is_censored: false, propagation_message_id: None, propagation_channel_id: None, @@ -975,11 +973,6 @@ impl MessageBuilder { self } - pub fn is_deleted(mut self, is_deleted: bool) -> Self { - self.is_deleted = is_deleted; - self - } - pub fn is_censored(mut self, is_censored: bool) -> Self { self.is_censored = is_censored; self @@ -1021,7 +1014,10 @@ impl MessageBuilder { propagation_message_id: self.propagation_message_id.map(u64_to_i64), propagation_channel_id: self.propagation_channel_id.map(u64_to_i64), replying_to_id: self.replying_to_id.map(u64_to_i64), - is_deleted: self.is_deleted, + + // You can't create a deleted message, this is always going to be false when + // initializing + is_deleted: false, is_edited: message.edited_timestamp.is_some(), is_censored: self.is_censored, }; diff --git a/src/groups/calls/events.rs b/src/groups/calls/events.rs index 2a9ef81..9c41255 100644 --- a/src/groups/calls/events.rs +++ b/src/groups/calls/events.rs @@ -3,7 +3,7 @@ use std::{error::Error, sync::Arc}; use async_trait::async_trait; use itertools::Itertools; use twilight_model::{ - gateway::payload::incoming::{MessageCreate, MessageUpdate}, + gateway::payload::incoming::{MessageCreate, MessageDelete, MessageUpdate}, id::Id, }; @@ -11,7 +11,9 @@ use crate::{ database::models::{Call, Channel, Message, User, UserIncident}, discord::sanitizing::SanitizeDiscordMarkdown, framework::{ - events::traits::{EventResult, OnMessageEditHandler, OnMessageHandler}, + events::traits::{ + EventResult, OnMessageDeleteHandler, OnMessageEditHandler, OnMessageHandler, + }, interactions::components::ActionRow, runtime::Runtime, }, @@ -345,3 +347,66 @@ impl OnMessageEditHandler for CallMessageEditHandler { Ok(()) } } + +#[derive(Debug)] +pub struct CallMessageDeleteHandler; + +#[async_trait] +impl OnMessageDeleteHandler for CallMessageDeleteHandler { + async fn on_message_delete( + &self, + event: &MessageDelete, + rt: Arc>, + ) -> EventResult { + let Some(channel) = Channel::get_by_id(event.channel_id.get(), &rt.state.db).await? else { + return Ok(()); + }; + + let call = if let Some(call_id) = channel.call_id { + if let Some(call) = Call::get_by_id(call_id, &rt.state.db).await? { + if !call.is_active() { + return Ok(()); + } + + call + } else { + return Ok(()); + } + } else { + return Ok(()); + }; + + let Some(mut message) = + Message::get_by_call_and_message_id(call.id, event.id.get(), &rt.state.db).await? + else { + return Ok(()); + }; + + let opposite_channel_id = call.other_party_channel_id(event.channel_id.get()); + let Some(opposite_channel) = Channel::get_by_id(opposite_channel_id, &rt.state.db).await? + else { + return Ok(()); + }; + + if let Some(propagation_message_id) = message.data.propagation_message_id { + if let Some((webhook_id, webhook_token)) = opposite_channel + .webhook_id + .zip(opposite_channel.webhook_token) + { + rt.http + .delete_webhook_message( + Id::new(webhook_id), + &webhook_token, + Id::new(i64_to_u64(propagation_message_id)), + ) + .await?; + + message.data.is_deleted = true; + + message.insert(&rt.state.db).await?; + } + } + + Ok(()) + } +} diff --git a/src/main.rs b/src/main.rs index a3ad0d0..2f928c2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -127,7 +127,7 @@ use crate::{ about::{commands::HelpCommand, components::HelpGoBackButton}, calls::{ commands::{CallCommand, FriendRequestCommand, HangupCommand, SkipCommand}, - events::{CallMessageEditHandler, CallMessageHandler}, + events::{CallMessageDeleteHandler, CallMessageEditHandler, CallMessageHandler}, }, gateway::events::{ReadyHandler, ReconnectHandler}, servers::{ @@ -234,6 +234,7 @@ async fn start(token: String, database_addr: String, shard: ShardId) { .on_reconnect(ReconnectHandler) .on_message(CallMessageHandler) .on_message_edit(CallMessageEditHandler) + .on_message_delete(CallMessageDeleteHandler) .on_server_create(ServerCreateHandler) .on_server_update(ServerUpdateHandler) .on_server_delete(ServerDeleteHandler);