Insert messages to DB when sent on call
This commit is contained in:
@@ -60,12 +60,11 @@ CREATE TABLE IF NOT EXISTS payphone.participants (
|
|||||||
PRIMARY KEY (call_id, user_id, channel_id)
|
PRIMARY KEY (call_id, user_id, channel_id)
|
||||||
);
|
);
|
||||||
|
|
||||||
-- TTL 30 days.
|
CREATE TYPE IF NOT EXISTS payphone.message (
|
||||||
CREATE TABLE IF NOT EXISTS payphone.messages (
|
id BIGINT,
|
||||||
call_id BIGINT,
|
call_id BIGINT,
|
||||||
message_id BIGINT,
|
|
||||||
author_id BIGINT,
|
|
||||||
|
|
||||||
|
author_id BIGINT,
|
||||||
author_name TEXT,
|
author_name TEXT,
|
||||||
author_avatar_url TEXT,
|
author_avatar_url TEXT,
|
||||||
author_mask ASCII,
|
author_mask ASCII,
|
||||||
@@ -82,6 +81,15 @@ CREATE TABLE IF NOT EXISTS payphone.messages (
|
|||||||
is_deleted BOOLEAN,
|
is_deleted BOOLEAN,
|
||||||
is_edited BOOLEAN,
|
is_edited BOOLEAN,
|
||||||
is_censored 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)
|
PRIMARY KEY (call_id, message_id)
|
||||||
);
|
);
|
||||||
@@ -95,21 +103,10 @@ CREATE TABLE IF NOT EXISTS payphone.servers (
|
|||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS payphone.reports (
|
CREATE TABLE IF NOT EXISTS payphone.reports (
|
||||||
report_id BIGINT,
|
report_id BIGINT,
|
||||||
|
user_id BIGINT,
|
||||||
|
|
||||||
message_author_id BIGINT,
|
message FROZEN<payphone.message>,
|
||||||
message_author_name TEXT,
|
replying_to FROZEN<payphone.message>,
|
||||||
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,
|
|
||||||
|
|
||||||
created_at TIMESTAMP,
|
created_at TIMESTAMP,
|
||||||
reviewed_at TIMESTAMP,
|
reviewed_at TIMESTAMP,
|
||||||
@@ -119,28 +116,18 @@ CREATE TABLE IF NOT EXISTS payphone.reports (
|
|||||||
reviewed_by_id BIGINT,
|
reviewed_by_id BIGINT,
|
||||||
resolution ASCII,
|
resolution ASCII,
|
||||||
|
|
||||||
PRIMARY KEY (message_author_id, report_id)
|
PRIMARY KEY (user_id, report_id)
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS payphone.user_incidents (
|
CREATE TABLE IF NOT EXISTS payphone.user_incidents (
|
||||||
user_id BIGINT,
|
user_id BIGINT,
|
||||||
incident_id BIGINT,
|
incident_id BIGINT,
|
||||||
|
report_id BIGINT,
|
||||||
|
|
||||||
-- ban, warning
|
-- ban, warning
|
||||||
type ASCII,
|
type ASCII,
|
||||||
|
|
||||||
call_id BIGINT,
|
message FROZEN<payphone.message>,
|
||||||
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,
|
|
||||||
|
|
||||||
reason TEXT,
|
reason TEXT,
|
||||||
|
|
||||||
@@ -164,4 +151,4 @@ CREATE TABLE IF NOT EXISTS payphone.server_incidents (
|
|||||||
created_at TIMESTAMP,
|
created_at TIMESTAMP,
|
||||||
expires_at TIMESTAMP,
|
expires_at TIMESTAMP,
|
||||||
duration ASCII
|
duration ASCII
|
||||||
);
|
);
|
||||||
|
|||||||
+154
-1
@@ -1,4 +1,5 @@
|
|||||||
use scylla::{
|
use scylla::{
|
||||||
|
DeserializeValue, SerializeValue,
|
||||||
client::session::Session,
|
client::session::Session,
|
||||||
deserialize::row::DeserializeRow,
|
deserialize::row::DeserializeRow,
|
||||||
errors::{ExecutionError, SingleRowError},
|
errors::{ExecutionError, SingleRowError},
|
||||||
@@ -11,12 +12,15 @@ use thiserror::Error;
|
|||||||
use time::{OffsetDateTime, UtcDateTime};
|
use time::{OffsetDateTime, UtcDateTime};
|
||||||
use twilight_http::Client;
|
use twilight_http::Client;
|
||||||
use twilight_model::{
|
use twilight_model::{
|
||||||
|
channel::Message as TwilightMessage,
|
||||||
guild::{Guild as TwilightGuild, GuildInfo as TwilightGuildInfo},
|
guild::{Guild as TwilightGuild, GuildInfo as TwilightGuildInfo},
|
||||||
id::Id,
|
id::Id,
|
||||||
user::User as TwilightUser,
|
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)]
|
#[derive(Debug, Error)]
|
||||||
pub enum DatabaseOrDiscordError {
|
pub enum DatabaseOrDiscordError {
|
||||||
@@ -827,3 +831,152 @@ impl Call {
|
|||||||
Ok(())
|
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(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use twilight_model::{gateway::payload::incoming::MessageCreate, id::Id};
|
|||||||
use twilight_validate::request::webhook_username;
|
use twilight_validate::request::webhook_username;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
database::models::{Call, Channel},
|
database::models::{Call, Channel, Message},
|
||||||
discord::images,
|
discord::images,
|
||||||
framework::{
|
framework::{
|
||||||
events::traits::{EventResult, OnMessageHandler},
|
events::traits::{EventResult, OnMessageHandler},
|
||||||
@@ -99,6 +99,17 @@ impl OnMessageHandler<State> for MessageRedirector {
|
|||||||
|
|
||||||
let profile = get_display_profile(event);
|
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
|
rt.http
|
||||||
.execute_webhook(Id::new(webhook_id), &webhook_token)
|
.execute_webhook(Id::new(webhook_id), &webhook_token)
|
||||||
.allowed_mentions(None)
|
.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 name: String,
|
||||||
pub avatar_url: String,
|
pub avatar_url: String,
|
||||||
|
pub mask: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_display_profile(event: &MessageCreate) -> DisplayProfile {
|
fn get_display_profile(event: &MessageCreate) -> DisplayProfile {
|
||||||
@@ -153,5 +167,10 @@ fn get_display_profile(event: &MessageCreate) -> DisplayProfile {
|
|||||||
event.author.discriminator as u64,
|
event.author.discriminator as u64,
|
||||||
);
|
);
|
||||||
|
|
||||||
DisplayProfile { name, avatar_url }
|
DisplayProfile {
|
||||||
|
id: event.author.id.get(),
|
||||||
|
name,
|
||||||
|
avatar_url,
|
||||||
|
mask: None,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user