get messages from timestamp
This commit is contained in:
BIN
db/1.sqlite
BIN
db/1.sqlite
Binary file not shown.
BIN
db/auth.sqlite
BIN
db/auth.sqlite
Binary file not shown.
@@ -5,8 +5,11 @@ use axum::{
|
|||||||
http::StatusCode,
|
http::StatusCode,
|
||||||
Json,
|
Json,
|
||||||
};
|
};
|
||||||
|
use chrono::NaiveDateTime;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug)]
|
||||||
pub struct CreateConversationValues{
|
pub struct CreateConversationValues{
|
||||||
//pub creator_id: i32, // already in token ?
|
//pub creator_id: i32, // already in token ?
|
||||||
@@ -76,3 +79,28 @@ where S: Send + Sync,
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug)]
|
||||||
|
pub struct GetMessagesValues{
|
||||||
|
pub conv_id: u32,
|
||||||
|
pub timestamp :Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct GetMessagesPayload(pub GetMessagesValues);
|
||||||
|
|
||||||
|
impl<S> FromRequest<S> for GetMessagesPayload
|
||||||
|
where S: Send + Sync,
|
||||||
|
{
|
||||||
|
type Rejection = (StatusCode, String);
|
||||||
|
|
||||||
|
async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> {
|
||||||
|
let Json(payload) = Json::<GetMessagesValues>::from_request(req, state)
|
||||||
|
.await
|
||||||
|
.map_err(|err| (StatusCode::BAD_REQUEST, format!("Invalid body: {}", err)))?;
|
||||||
|
|
||||||
|
Ok(GetMessagesPayload(payload))
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,10 +5,12 @@ use axum::{
|
|||||||
}, http::StatusCode, response::{sse::KeepAlive, IntoResponse}
|
}, http::StatusCode, response::{sse::KeepAlive, IntoResponse}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use chrono::NaiveDateTime;
|
||||||
use rusqlite::params;
|
use rusqlite::params;
|
||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
use crate::chat::extractor::{
|
use crate::chat::extractor::{
|
||||||
AddUserConversationPayload, CreateConversationPayload, SendMessagePayload
|
AddUserConversationPayload, CreateConversationPayload, GetMessagesPayload, SendMessagePayload
|
||||||
};
|
};
|
||||||
use crate::utils::db_pool::{AppState};
|
use crate::utils::db_pool::{AppState};
|
||||||
use crate::utils::auth::AuthClaims;
|
use crate::utils::auth::AuthClaims;
|
||||||
@@ -127,3 +129,57 @@ pub async fn send_message(
|
|||||||
Err(err) => (StatusCode::INTERNAL_SERVER_ERROR, format!("Error when adding the message : {err}")),
|
Err(err) => (StatusCode::INTERNAL_SERVER_ERROR, format!("Error when adding the message : {err}")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
struct Message {
|
||||||
|
id: i32,
|
||||||
|
sender_id: i32,
|
||||||
|
content: String,
|
||||||
|
sent_at: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub async fn get_message(
|
||||||
|
State(state): State<AppState>,
|
||||||
|
AuthClaims {user_id, hotel_id,username}: AuthClaims,
|
||||||
|
GetMessagesPayload(payload):GetMessagesPayload
|
||||||
|
) -> Result<impl IntoResponse, (StatusCode, String)> {
|
||||||
|
|
||||||
|
let pool = state.hotel_pools.get_pool(hotel_id);
|
||||||
|
|
||||||
|
let conn = pool.get()
|
||||||
|
.map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "Pool error".to_string()))?;
|
||||||
|
|
||||||
|
let from_time = match payload.timestamp.as_deref() {
|
||||||
|
Some("0") | None => "1970-01-01 00:00:00", // default to epoch
|
||||||
|
Some(ts) => ts,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut stmt = conn.prepare(
|
||||||
|
"SELECT id, sender_id, content, sent_at
|
||||||
|
FROM message
|
||||||
|
WHERE conversation_id = ?1
|
||||||
|
AND sent_at > ?2
|
||||||
|
ORDER BY sent_at DESC
|
||||||
|
LIMIT 50"
|
||||||
|
).map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "Prepare failed".to_string()))?;
|
||||||
|
|
||||||
|
|
||||||
|
let messages = stmt.query_map(
|
||||||
|
params![payload.conv_id, from_time],
|
||||||
|
|row| {
|
||||||
|
Ok(Message {
|
||||||
|
id: row.get(0)?,
|
||||||
|
sender_id: row.get(1)?,
|
||||||
|
content: row.get(2)?,
|
||||||
|
sent_at: row.get(3)?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
).map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "Query failed".to_string()))?
|
||||||
|
.collect::<Result<Vec<_>, _>>()
|
||||||
|
.map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "Collect failed".to_string()))?;
|
||||||
|
|
||||||
|
Ok((StatusCode::OK, serde_json::to_string(&messages).unwrap()))
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,12 +1,13 @@
|
|||||||
use axum::{
|
use axum::{
|
||||||
Router,
|
Router,
|
||||||
routing::put,
|
routing::put,
|
||||||
routing::post
|
routing::post,
|
||||||
|
routing::get,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::utils::db_pool::AppState;
|
use crate::utils::db_pool::AppState;
|
||||||
use crate::chat::handlers::{
|
use crate::chat::handlers::{
|
||||||
create_conversation,add_user_to_conv,send_message
|
create_conversation,add_user_to_conv,send_message,get_message
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -19,5 +20,6 @@ pub fn chat_routes() -> Router<AppState> {
|
|||||||
.route("/create_conversation", post (create_conversation))
|
.route("/create_conversation", post (create_conversation))
|
||||||
.route("/add_users_conv", put(add_user_to_conv))
|
.route("/add_users_conv", put(add_user_to_conv))
|
||||||
.route("/send_message", post(send_message))
|
.route("/send_message", post(send_message))
|
||||||
|
.route("/get_message", get(get_message))
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user