gitdataai/lib/api/src/channel/rest_message.rs
2026-05-30 01:38:40 +08:00

226 lines
6.1 KiB
Rust

use actix_web::{HttpRequest, HttpResponse, web};
use channel::ChannelBus;
use channel::http::{WsHandler, WsInMessage};
use serde::Deserialize;
use uuid::Uuid;
use super::rest::{channel_err, created_json, extract_user, ok_json};
use crate::error::ApiError;
#[derive(Debug, Deserialize, utoipa::ToSchema)]
pub struct CreateMessageRequest {
pub content: String,
pub content_type: Option<String>,
pub thread: Option<Uuid>,
pub in_reply_to: Option<Uuid>,
}
#[derive(Debug, Deserialize, utoipa::ToSchema)]
pub struct UpdateMessageRequest {
pub content: String,
}
#[derive(Debug, Deserialize, utoipa::IntoParams)]
pub struct MessageListParams {
pub before_seq: Option<i64>,
pub after_seq: Option<i64>,
pub limit: Option<u64>,
}
#[derive(Debug, Deserialize, utoipa::IntoParams)]
pub struct MessageAroundParams {
pub seq: i64,
pub limit: Option<u64>,
}
#[derive(Debug, Deserialize, utoipa::IntoParams)]
pub struct MissedMessagesParams {
pub after_seq: i64,
pub limit: Option<i64>,
}
#[derive(Debug, Deserialize, utoipa::IntoParams)]
pub struct SearchParams {
pub q: String,
pub room: Option<Uuid>,
pub limit: Option<u64>,
pub offset: Option<u64>,
}
#[utoipa::path(
post,
path = "/api/v1/ws/rooms/{room_id}/messages",
request_body = CreateMessageRequest,
responses((status = 201, description = "Message created")),
tag = "channel",
)]
pub async fn create_message(
req: HttpRequest,
room_id: web::Path<Uuid>,
body: web::Json<CreateMessageRequest>,
bus: web::Data<ChannelBus>,
) -> Result<HttpResponse, ApiError> {
let user_id = extract_user(&req)?;
let msg = WsInMessage::MessageCreate {
room: room_id.into_inner(),
content: body.content.clone(),
content_type: body.content_type.clone(),
thread: body.thread,
in_reply_to: body.in_reply_to,
};
let result = WsHandler::handle(&bus, user_id, msg)
.await
.map_err(channel_err)?;
Ok(created_json(result))
}
#[utoipa::path(
patch,
path = "/api/v1/ws/messages/{message_id}",
request_body = UpdateMessageRequest,
responses((status = 200, description = "Message updated")),
tag = "channel",
)]
pub async fn update_message(
req: HttpRequest,
message_id: web::Path<Uuid>,
body: web::Json<UpdateMessageRequest>,
bus: web::Data<ChannelBus>,
) -> Result<HttpResponse, ApiError> {
let user_id = extract_user(&req)?;
let msg = WsInMessage::MessageUpdate {
message: message_id.into_inner(),
content: body.content.clone(),
};
let result = WsHandler::handle(&bus, user_id, msg)
.await
.map_err(channel_err)?;
Ok(ok_json(result))
}
#[utoipa::path(
delete,
path = "/api/v1/ws/messages/{message_id}",
responses((status = 200, description = "Message revoked")),
tag = "channel",
)]
pub async fn revoke_message(
req: HttpRequest,
message_id: web::Path<Uuid>,
bus: web::Data<ChannelBus>,
) -> Result<HttpResponse, ApiError> {
let user_id = extract_user(&req)?;
let msg = WsInMessage::MessageRevoke {
message: message_id.into_inner(),
};
let result = WsHandler::handle(&bus, user_id, msg)
.await
.map_err(channel_err)?;
Ok(ok_json(result))
}
#[utoipa::path(
get,
path = "/api/v1/ws/rooms/{room_id}/messages",
params(MessageListParams),
responses((status = 200, description = "Message list")),
tag = "channel",
)]
pub async fn list_messages(
req: HttpRequest,
room_id: web::Path<Uuid>,
params: web::Query<MessageListParams>,
bus: web::Data<ChannelBus>,
) -> Result<HttpResponse, ApiError> {
let user_id = extract_user(&req)?;
let msg = WsInMessage::MessageList {
room: room_id.into_inner(),
before_seq: params.before_seq,
after_seq: params.after_seq,
limit: params.limit,
};
let result = WsHandler::handle(&bus, user_id, msg)
.await
.map_err(channel_err)?;
Ok(ok_json(result))
}
#[utoipa::path(
get,
path = "/api/v1/ws/rooms/{room_id}/messages/around",
params(MessageAroundParams),
responses((status = 200, description = "Messages around seq")),
tag = "channel",
)]
pub async fn messages_around(
req: HttpRequest,
room_id: web::Path<Uuid>,
params: web::Query<MessageAroundParams>,
bus: web::Data<ChannelBus>,
) -> Result<HttpResponse, ApiError> {
let user_id = extract_user(&req)?;
let msg = WsInMessage::MessageAround {
room: room_id.into_inner(),
seq: params.seq,
limit: params.limit,
};
let result = WsHandler::handle(&bus, user_id, msg)
.await
.map_err(channel_err)?;
Ok(ok_json(result))
}
#[utoipa::path(
get,
path = "/api/v1/ws/rooms/{room_id}/messages/missed",
params(MissedMessagesParams),
responses((status = 200, description = "Missed messages")),
tag = "channel",
)]
pub async fn missed_messages(
req: HttpRequest,
room_id: web::Path<Uuid>,
params: web::Query<MissedMessagesParams>,
bus: web::Data<ChannelBus>,
) -> Result<HttpResponse, ApiError> {
let user_id = extract_user(&req)?;
let msg = WsInMessage::MissedMessages {
room: room_id.into_inner(),
after_seq: params.after_seq,
limit: params.limit,
};
let result = WsHandler::handle(&bus, user_id, msg)
.await
.map_err(channel_err)?;
Ok(ok_json(result))
}
#[utoipa::path(
get,
path = "/api/v1/ws/search",
params(SearchParams),
responses((status = 200, description = "Search results")),
tag = "channel",
)]
pub async fn search(
req: HttpRequest,
params: web::Query<SearchParams>,
bus: web::Data<ChannelBus>,
) -> Result<HttpResponse, ApiError> {
let user_id = extract_user(&req)?;
let msg = WsInMessage::Search {
q: params.q.clone(),
room: params.room,
start_time: None,
end_time: None,
sender_id: None,
content_type: None,
limit: params.limit,
offset: params.offset,
};
let result = WsHandler::handle(&bus, user_id, msg)
.await
.map_err(channel_err)?;
Ok(ok_json(result))
}