use revolt_config::config; use revolt_database::{ util::{idempotency::IdempotencyKey, reference::Reference}, Database, Message, AMQP, }; use revolt_models::v0; use revolt_permissions::{ChannelPermission, PermissionValue}; use revolt_result::{create_error, Result}; use rocket::{serde::json::Json, State}; use validator::Validate; /// # Executes a webhook /// /// Executes a webhook and sends a message #[openapi(tag = "Webhooks")] #[post("//", data = "")] pub async fn webhook_execute( db: &State, amqp: &State, webhook_id: Reference, token: String, data: Json, idempotency: IdempotencyKey, ) -> Result> { let data = data.into_inner(); data.validate().map_err(|error| { create_error!(FailedValidation { error: error.to_string() }) })?; let webhook = webhook_id.as_webhook(db).await?; webhook.assert_token(&token)?; let permissions: PermissionValue = webhook.permissions.into(); permissions.throw_if_lacking_channel_permission(ChannelPermission::SendMessage)?; if data.attachments.as_ref().is_some_and(|v| !v.is_empty()) { permissions.throw_if_lacking_channel_permission(ChannelPermission::UploadFiles)?; } if data.embeds.as_ref().is_some_and(|v| !v.is_empty()) { permissions.throw_if_lacking_channel_permission(ChannelPermission::SendEmbeds)?; } if data.masquerade.is_some() { permissions.throw_if_lacking_channel_permission(ChannelPermission::Masquerade)?; } if data.interactions.is_some() { permissions.throw_if_lacking_channel_permission(ChannelPermission::React)?; } let channel = db.fetch_channel(&webhook.channel_id).await?; Ok(Json( Message::create_from_api( db, Some(amqp), channel, data, v0::MessageAuthor::Webhook(&webhook.into()), None, None, config().await.features.limits.default, idempotency, true, true, ) .await? .into_model(None, None), )) }