forked from jmug/stoatchat
79 lines
2.6 KiB
Rust
79 lines
2.6 KiB
Rust
use revolt_database::util::permissions::DatabasePermissionQuery;
|
|
use revolt_database::{
|
|
util::idempotency::IdempotencyKey, util::reference::Reference, Database, User,
|
|
};
|
|
use revolt_database::{Interactions, Message};
|
|
use revolt_models::v0;
|
|
use revolt_permissions::{calculate_channel_permissions, ChannelPermission};
|
|
use revolt_result::{create_error, Result};
|
|
use rocket::serde::json::Json;
|
|
use rocket::State;
|
|
use validator::Validate;
|
|
|
|
/// # Send Message
|
|
///
|
|
/// Sends a message to the given channel.
|
|
#[openapi(tag = "Messaging")]
|
|
#[post("/<target>/messages", data = "<data>")]
|
|
pub async fn message_send(
|
|
db: &State<Database>,
|
|
user: User,
|
|
target: Reference,
|
|
data: Json<v0::DataMessageSend>,
|
|
idempotency: IdempotencyKey,
|
|
) -> Result<Json<v0::Message>> {
|
|
let data = data.into_inner();
|
|
data.validate().map_err(|error| {
|
|
create_error!(FailedValidation {
|
|
error: error.to_string()
|
|
})
|
|
})?;
|
|
|
|
// Ensure we have permissions to send a message
|
|
let channel = target.as_channel(db).await?;
|
|
|
|
let mut query = DatabasePermissionQuery::new(db, &user).channel(&channel);
|
|
let permissions = calculate_channel_permissions(&mut query).await;
|
|
permissions.throw_if_lacking_channel_permission(ChannelPermission::SendMessage)?;
|
|
|
|
// Verify permissions for masquerade
|
|
if let Some(masq) = &data.masquerade {
|
|
permissions.throw_if_lacking_channel_permission(ChannelPermission::Masquerade)?;
|
|
|
|
if masq.colour.is_some() {
|
|
permissions.throw_if_lacking_channel_permission(ChannelPermission::ManageRole)?;
|
|
}
|
|
}
|
|
|
|
// Check permissions for embeds
|
|
if data.embeds.as_ref().is_some_and(|v| !v.is_empty()) {
|
|
permissions.throw_if_lacking_channel_permission(ChannelPermission::SendEmbeds)?;
|
|
}
|
|
|
|
// Check permissions for files
|
|
if data.attachments.as_ref().is_some_and(|v| !v.is_empty()) {
|
|
permissions.throw_if_lacking_channel_permission(ChannelPermission::UploadFiles)?;
|
|
}
|
|
|
|
// Ensure interactions information is correct
|
|
if let Some(interactions) = &data.interactions {
|
|
let interactions: Interactions = interactions.clone().into();
|
|
interactions.validate(db, &permissions).await?;
|
|
}
|
|
|
|
// Create the message
|
|
let author: v0::User = user.clone().into(db, Some(&user)).await;
|
|
Ok(Json(
|
|
Message::create_from_api(
|
|
db,
|
|
channel,
|
|
data,
|
|
v0::MessageAuthor::User(&author),
|
|
idempotency,
|
|
permissions.has_channel_permission(ChannelPermission::SendEmbeds),
|
|
)
|
|
.await?
|
|
.into(),
|
|
))
|
|
}
|