mirror of
https://github.com/stoatchat/stoatchat.git
synced 2026-07-14 13:36:59 +00:00
feat(revcord): post message request handling
This commit is contained in:
@@ -62,12 +62,16 @@ async fn main() {
|
||||
|
||||
let auth = Auth::new(mongo_db.database("revolt"), Config::default());
|
||||
let rocket = rocket::build();
|
||||
routes::mount(rocket)
|
||||
let r = routes::mount(rocket)
|
||||
.mount("/", rocket_cors::catch_all_options_routes())
|
||||
.manage(auth)
|
||||
.manage(db)
|
||||
.manage(cors.clone())
|
||||
.attach(cors)
|
||||
.attach(cors);
|
||||
|
||||
let config = r.figment().clone().merge((rocket::Config::PORT, 1111));
|
||||
|
||||
r.configure(config)
|
||||
.launch()
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use revolt_quark::{Database, Ref, Result, EmptyResponse, Error};
|
||||
use revcord_models::{ user::User};
|
||||
use rocket::{serde::json::Json, form::{FromForm, Form, ValueField, Result as FormResult, DataField, Errors as FormErrors, Error as FormError}, data::{FromData, Outcome, Data}, http::Status, fs::TempFile, };
|
||||
use rocket_okapi::request::OpenApiFromData;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use validator::Validate;
|
||||
|
||||
#[derive(Debug, FromForm)]
|
||||
pub struct MessagePostForm<'r> {
|
||||
pub payload_json: Option<MessagePostJson>,
|
||||
pub files: HashMap<String, TempFile<'r>>
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Validate, JsonSchema, Debug, Clone)]
|
||||
pub struct MessagePostJson {
|
||||
pub content: Option<String>,
|
||||
pub tts: Option<bool>,
|
||||
// pub embeds: Option<Vec<DiscordEmbed>>,
|
||||
// pub allows_mentions: Option<DiscordAllowedMentions>,
|
||||
// pub message_reference: Option<DiscordMessageReference>,
|
||||
// pub attachments: Option<Vec<DiscordAttachment>>,
|
||||
pub flags: Option<u64>
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl<'r> rocket::form::FromFormField<'r> for MessagePostJson { // specify the full path because otherwise Json::from_data messes up
|
||||
fn from_value(field: ValueField<'r>) -> FormResult<'r, Self> {
|
||||
serde_json::from_str(field.value).map_err(|e| {
|
||||
let mut errors = FormErrors::new();
|
||||
errors.push(FormError::validation(format!("{e:?}")));
|
||||
errors
|
||||
})
|
||||
}
|
||||
|
||||
async fn from_data(_: DataField<'r, '_>) -> FormResult<'r, Self> {
|
||||
let mut errors = FormErrors::new();
|
||||
errors.push(FormError::validation("payload_json must be a string"));
|
||||
Err(errors)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum MessageBody<'r> {
|
||||
Form(MessagePostForm<'r>),
|
||||
Json(MessagePostJson)
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl<'r> FromData<'r> for MessageBody<'r> {
|
||||
type Error = Error;
|
||||
|
||||
async fn from_data(req: &'r rocket::Request<'_>, data: Data<'r>) -> Outcome<'r, Self> {
|
||||
if let Some(content_type) = req.headers().get_one("content-type") {
|
||||
println!("{content_type}");
|
||||
match content_type.split(';').next().unwrap() {
|
||||
"application/json" => {
|
||||
match Json::<MessagePostJson>::from_data(req, data).await {
|
||||
Outcome::Success(json) => Outcome::Success(Self::Json(json.into_inner())),
|
||||
Outcome::Failure(_) => Outcome::Failure((Status::BadRequest, Error::LabelMe)),
|
||||
_ => unreachable!()
|
||||
}
|
||||
},
|
||||
"multipart/form-data" => {
|
||||
match Form::<MessagePostForm>::from_data(req, data).await {
|
||||
Outcome::Success(form) => Outcome::Success(Self::Form(form.into_inner())),
|
||||
Outcome::Failure(_) => Outcome::Failure((Status::BadRequest, Error::LabelMe)),
|
||||
_ => unreachable!()
|
||||
}
|
||||
},
|
||||
_ => Outcome::Failure((Status::BadRequest, Error::LabelMe))
|
||||
}
|
||||
} else {
|
||||
Outcome::Failure((Status::BadRequest, Error::LabelMe))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'r> OpenApiFromData<'r> for MessageBody<'r> {
|
||||
fn request_body(gen: &mut rocket_okapi::gen::OpenApiGenerator) -> rocket_okapi::Result<rocket_okapi::okapi::openapi3::RequestBody> {
|
||||
Ok(rocket_okapi::okapi::openapi3::RequestBody::default())
|
||||
}
|
||||
}
|
||||
|
||||
#[openapi(tag = "Messages")]
|
||||
#[post("/<target>/messages", data="<body>")]
|
||||
pub async fn req(user: User, target: Ref, body: MessageBody<'_>) -> Result<EmptyResponse> {
|
||||
println!("{body:?}");
|
||||
|
||||
Ok(EmptyResponse)
|
||||
}
|
||||
1
crates/revcord/api/src/routes/channels/messages/mod.rs
Normal file
1
crates/revcord/api/src/routes/channels/messages/mod.rs
Normal file
@@ -0,0 +1 @@
|
||||
pub mod message_send;
|
||||
@@ -1,10 +1,13 @@
|
||||
use rocket::Route;
|
||||
use rocket_okapi::okapi::openapi3::OpenApi;
|
||||
|
||||
mod messages;
|
||||
|
||||
mod fetch_channel;
|
||||
|
||||
pub fn routes() -> (Vec<Route>, OpenApi) {
|
||||
openapi_get_routes_spec![
|
||||
fetch_channel::req,
|
||||
messages::message_send::req
|
||||
]
|
||||
}
|
||||
|
||||
@@ -19,5 +19,8 @@ pub fn mount(mut rocket: Rocket<Build>) -> Rocket<Build> {
|
||||
|
||||
|
||||
fn custom_openapi_spec() -> OpenApi {
|
||||
OpenApi::default()
|
||||
OpenApi {
|
||||
openapi: OpenApi::default_version(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,9 +16,11 @@ pub trait QuarkConversion: Sized {
|
||||
}
|
||||
|
||||
pub fn to_snowflake<T, S: ToString>(ulid: S) -> twilight_model::id::Id<T> {
|
||||
todo!()
|
||||
unsafe {
|
||||
twilight_model::id::Id::new_unchecked(1)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_ulid<T>(snowflake: twilight_model::id::Id<T>) -> String {
|
||||
todo!()
|
||||
String::from("1")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user