diff --git a/src/api/v1/servers/uuid/channels/uuid/messages.rs b/src/api/v1/servers/uuid/channels/uuid/messages.rs index e69de29..70aa10b 100644 --- a/src/api/v1/servers/uuid/channels/uuid/messages.rs +++ b/src/api/v1/servers/uuid/channels/uuid/messages.rs @@ -0,0 +1,73 @@ +use actix_web::{get, web, Error, HttpRequest, HttpResponse}; +use serde::Deserialize; +use crate::{api::v1::auth::check_access_token, structs::{Channel, Member}, utils::get_auth_header, Data}; +use ::uuid::Uuid; +use log::error; + +#[derive(Deserialize)] +struct MessageRequest { + amount: i64, + offset: i64, +} + +#[get("{uuid}/channels/{channel_uuid}/messages")] +pub async fn res(req: HttpRequest, path: web::Path<(Uuid, Uuid)>, message_request: web::Json, data: web::Data) -> Result { + let headers = req.headers(); + + let auth_header = get_auth_header(headers); + + if let Err(error) = auth_header { + return Ok(error) + } + + let (guild_uuid, channel_uuid) = path.into_inner(); + + let authorized = check_access_token(auth_header.unwrap(), &data.pool).await; + + if let Err(error) = authorized { + return Ok(error) + } + + let uuid = authorized.unwrap(); + + let member = Member::fetch_one(&data.pool, uuid, guild_uuid).await; + + if let Err(error) = member { + return Ok(error); + } + + let cache_result = data.get_cache_key(format!("{}", channel_uuid)).await; + + let mut channel_raw: Option = None; + + if let Ok(cache_hit) = cache_result { + channel_raw = Some(serde_json::from_str(&cache_hit).unwrap()) + } + + if channel_raw.is_none() { + let channel_result = Channel::fetch_one(&data.pool, guild_uuid, channel_uuid).await; + + if let Err(error) = channel_result { + return Ok(error) + } + + channel_raw = Some(channel_result.unwrap()); + + let cache_result = data.set_cache_key(format!("{}", channel_uuid), channel_raw.clone().unwrap(), 60).await; + + if let Err(error) = cache_result { + error!("{}", error); + return Ok(HttpResponse::InternalServerError().finish()); + } + } + + let channel = channel_raw.unwrap(); + + let messages = channel.fetch_messages(&data.pool, message_request.amount, message_request.offset).await; + + if let Err(error) = messages { + return Ok(error) + } + + Ok(HttpResponse::Ok().json(messages.unwrap())) +} diff --git a/src/structs.rs b/src/structs.rs index 0826c42..b5ad6ea 100644 --- a/src/structs.rs +++ b/src/structs.rs @@ -1,6 +1,6 @@ use std::str::FromStr; -use serde::Serialize; +use serde::{Deserialize, Serialize}; use sqlx::{prelude::FromRow, Pool, Postgres}; use uuid::Uuid; use actix_web::HttpResponse; @@ -8,7 +8,7 @@ use log::error; use crate::Data; -#[derive(Serialize, Clone)] +#[derive(Serialize, Deserialize, Clone)] pub struct Channel { pub uuid: Uuid, pub guild_uuid: Uuid, @@ -32,7 +32,7 @@ impl ChannelPermissionBuilder { } } -#[derive(Serialize, Clone, FromRow)] +#[derive(Serialize, Deserialize, Clone, FromRow)] pub struct ChannelPermission { pub role_uuid: Uuid, pub permissions: i32 @@ -155,6 +155,23 @@ impl Channel { Ok(channel) } + + pub async fn fetch_messages(&self, pool: &Pool, amount: i64, offset: i64) -> Result, HttpResponse> { + let row = sqlx::query_as(&format!("SELECT uuid, user_uuid, message FROM channels WHERE channel_uuid = '{}' ORDER BY uuid LIMIT $1 OFFSET $2", self.uuid)) + .bind(amount) + .bind(offset) + .fetch_all(pool) + .await; + + if let Err(error) = row { + error!("{}", error); + return Err(HttpResponse::InternalServerError().finish()); + } + + let message_builders: Vec = row.unwrap(); + + Ok(message_builders.iter().map(|b| b.build()).collect()) + } } #[derive(Clone, Copy)] @@ -349,3 +366,30 @@ impl Member { }) } } + +#[derive(FromRow)] +struct MessageBuilder { + uuid: String, + channel_uuid: String, + user_uuid: String, + message: String, +} + +impl MessageBuilder { + fn build(&self) -> Message { + Message { + uuid: Uuid::from_str(&self.uuid).unwrap(), + channel_uuid: Uuid::from_str(&self.channel_uuid).unwrap(), + user_uuid: Uuid::from_str(&self.user_uuid).unwrap(), + message: self.message.clone(), + } + } +} + +#[derive(Serialize)] +pub struct Message { + uuid: Uuid, + channel_uuid: Uuid, + user_uuid: Uuid, + message: String, +}