Insert messages to DB when sent on call

This commit is contained in:
2025-08-14 13:04:12 -03:00
parent 8173a508ad
commit 634c8eff8c
3 changed files with 195 additions and 36 deletions
+18 -31
View File
@@ -60,12 +60,11 @@ CREATE TABLE IF NOT EXISTS payphone.participants (
PRIMARY KEY (call_id, user_id, channel_id)
);
-- TTL 30 days.
CREATE TABLE IF NOT EXISTS payphone.messages (
CREATE TYPE IF NOT EXISTS payphone.message (
id BIGINT,
call_id BIGINT,
message_id BIGINT,
author_id BIGINT,
author_id BIGINT,
author_name TEXT,
author_avatar_url TEXT,
author_mask ASCII,
@@ -82,6 +81,15 @@ CREATE TABLE IF NOT EXISTS payphone.messages (
is_deleted BOOLEAN,
is_edited BOOLEAN,
is_censored BOOLEAN,
);
-- TTL 30 days.
CREATE TABLE IF NOT EXISTS payphone.messages (
call_id BIGINT,
message_id BIGINT,
author_id BIGINT,
data FROZEN<payphone.message>,
PRIMARY KEY (call_id, message_id)
);
@@ -95,21 +103,10 @@ CREATE TABLE IF NOT EXISTS payphone.servers (
CREATE TABLE IF NOT EXISTS payphone.reports (
report_id BIGINT,
user_id BIGINT,
message_author_id BIGINT,
message_author_name TEXT,
message_author_avatar_url TEXT,
message_author_mask ASCII,
message_id BIGINT,
message_content TEXT,
message_attachments LIST<TEXT>,
message_sticker BIGINT,
message_replying_to_id BIGINT,
message_replying_to_content TEXT,
message_replying_to_attachments LIST<TEXT>,
message_replying_to_sticker BIGINT,
message FROZEN<payphone.message>,
replying_to FROZEN<payphone.message>,
created_at TIMESTAMP,
reviewed_at TIMESTAMP,
@@ -119,28 +116,18 @@ CREATE TABLE IF NOT EXISTS payphone.reports (
reviewed_by_id BIGINT,
resolution ASCII,
PRIMARY KEY (message_author_id, report_id)
PRIMARY KEY (user_id, report_id)
);
CREATE TABLE IF NOT EXISTS payphone.user_incidents (
user_id BIGINT,
incident_id BIGINT,
report_id BIGINT,
-- ban, warning
type ASCII,
call_id BIGINT,
report_id BIGINT,
message_id BIGINT,
message_content TEXT,
message_attachments LIST<TEXT>,
message_sticker BIGINT,
message_replying_to_id BIGINT,
message_replying_to_content TEXT,
message_replying_to_attachments LIST<TEXT>,
message_replying_to_sticker BIGINT,
message FROZEN<payphone.message>,
reason TEXT,
+154 -1
View File
@@ -1,4 +1,5 @@
use scylla::{
DeserializeValue, SerializeValue,
client::session::Session,
deserialize::row::DeserializeRow,
errors::{ExecutionError, SingleRowError},
@@ -11,12 +12,15 @@ use thiserror::Error;
use time::{OffsetDateTime, UtcDateTime};
use twilight_http::Client;
use twilight_model::{
channel::Message as TwilightMessage,
guild::{Guild as TwilightGuild, GuildInfo as TwilightGuildInfo},
id::Id,
user::User as TwilightUser,
};
use crate::{constants::DEFAULT_PREFIX, utils::get_random_u64};
use crate::{
constants::DEFAULT_PREFIX, groups::calls::events::DisplayProfile, utils::get_random_u64,
};
#[derive(Debug, Error)]
pub enum DatabaseOrDiscordError {
@@ -827,3 +831,152 @@ impl Call {
Ok(())
}
}
#[derive(Debug, Clone, SerializeValue, DeserializeValue)]
pub struct MessageData {
pub id: i64,
pub call_id: i64,
pub author_id: i64,
pub author_name: String,
pub author_avatar_url: String,
pub author_mask: Option<String>,
pub content: String,
pub attachments: Vec<String>,
pub sticker: Option<i64>,
pub propagation_message_id: Option<i64>,
pub propagation_channel_id: Option<i64>,
pub replying_to_id: Option<i64>,
pub is_deleted: bool,
pub is_edited: bool,
pub is_censored: bool,
}
#[derive(Debug, Error)]
#[error("The message was missing either the event's message, the user's profile, or the call ID")]
pub struct MessageBuilderError;
#[derive(Default)]
pub struct MessageBuilder {
message: Option<TwilightMessage>,
profile: Option<DisplayProfile>,
call_id: Option<u64>,
}
impl MessageBuilder {
fn new() -> Self {
Self {
message: None,
profile: None,
call_id: None,
}
}
pub fn message(mut self, message: TwilightMessage) -> Self {
self.message = Some(message);
self
}
pub fn profile(mut self, profile: DisplayProfile) -> Self {
self.profile = Some(profile);
self
}
pub fn call_id(mut self, call_id: u64) -> Self {
self.call_id = Some(call_id);
self
}
pub fn build(self) -> Result<Message, MessageBuilderError> {
let message = self.message.ok_or(MessageBuilderError)?;
let profile = self.profile.ok_or(MessageBuilderError)?;
let call_id = self.call_id.ok_or(MessageBuilderError)?;
let data = MessageData {
id: u64_to_i64(message.id.get()),
call_id: u64_to_i64(call_id),
author_id: u64_to_i64(profile.id),
author_name: profile.name.clone(),
author_avatar_url: profile.avatar_url.clone(),
author_mask: profile.mask,
content: message.content,
attachments: message.attachments.iter().map(|a| a.url.clone()).collect(),
sticker: message
.sticker_items
.first()
.map(|s| u64_to_i64(s.id.get())),
propagation_message_id: None,
propagation_channel_id: None,
replying_to_id: None,
is_deleted: false,
is_edited: message.edited_timestamp.is_some(),
is_censored: false,
};
Ok(Message {
call_id,
message_id: message.id.get(),
author_id: profile.id,
data,
})
}
}
#[derive(Debug, Clone)]
pub struct Message {
pub call_id: u64,
pub message_id: u64,
pub author_id: u64,
pub data: MessageData,
}
impl<'a> Object<'a> for Message {
type Row = (i64, i64, i64, MessageData);
fn from_row(row: Self::Row) -> Self {
Self {
call_id: i64_to_u64(row.0),
message_id: i64_to_u64(row.1),
author_id: i64_to_u64(row.2),
data: row.3,
}
}
fn to_row(value: Self) -> Self::Row {
(
u64_to_i64(value.call_id),
u64_to_i64(value.message_id),
u64_to_i64(value.author_id),
value.data,
)
}
}
impl Message {
pub fn build() -> MessageBuilder {
MessageBuilder::new()
}
pub async fn insert(&self, session: &Session) -> Result<(), DatabaseError> {
session
.query_unpaged(
r#"
INSERT INTO payphone.messages (
call_id,
message_id,
author_id,
data
) VALUES (?, ?, ?, ?);
"#,
Self::to_row(self.clone()),
)
.await
.map_err(DatabaseError::QueryError)?;
Ok(())
}
}
+22 -3
View File
@@ -5,7 +5,7 @@ use twilight_model::{gateway::payload::incoming::MessageCreate, id::Id};
use twilight_validate::request::webhook_username;
use crate::{
database::models::{Call, Channel},
database::models::{Call, Channel, Message},
discord::images,
framework::{
events::traits::{EventResult, OnMessageHandler},
@@ -99,6 +99,17 @@ impl OnMessageHandler<State> for MessageRedirector {
let profile = get_display_profile(event);
Message::build()
.call_id(call.id)
.message(event.0.clone())
.profile(profile.clone())
.build()
.expect(
"The message builder was missing either the call ID, the message, or the profile",
)
.insert(&rt.state.db)
.await?;
rt.http
.execute_webhook(Id::new(webhook_id), &webhook_token)
.allowed_mentions(None)
@@ -118,9 +129,12 @@ impl OnMessageHandler<State> for MessageRedirector {
}
}
struct DisplayProfile {
#[derive(Debug, Clone)]
pub struct DisplayProfile {
pub id: u64,
pub name: String,
pub avatar_url: String,
pub mask: Option<String>,
}
fn get_display_profile(event: &MessageCreate) -> DisplayProfile {
@@ -153,5 +167,10 @@ fn get_display_profile(event: &MessageCreate) -> DisplayProfile {
event.author.discriminator as u64,
);
DisplayProfile { name, avatar_url }
DisplayProfile {
id: event.author.id.get(),
name,
avatar_url,
mask: None,
}
}