use serde::{Deserialize, Serialize};
use crate::error::HttpError;
use crate::http::client::HttpClient;
use crate::http::routing::Route;
use crate::model::id::{ChannelId, GuildId};
use crate::model::message::{Embed, Message};
use crate::model::user::User;
#[derive(Debug, Clone, Deserialize)]
pub struct Webhook {
pub id: String,
#[serde(default)]
pub name: Option<String>,
#[serde(default)]
pub avatar: Option<String>,
#[serde(default)]
pub channel_id: Option<ChannelId>,
#[serde(default)]
pub guild_id: Option<GuildId>,
#[serde(default)]
pub user: Option<User>,
#[serde(default)]
pub token: Option<String>,
}
#[derive(Debug, Default, Serialize)]
pub struct CreateWebhook {
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub avatar: Option<String>,
}
impl CreateWebhook {
pub fn new(name: impl Into<String>) -> Self {
Self {
name: name.into(),
avatar: None,
}
}
}
#[derive(Debug, Default, Serialize)]
pub struct ModifyWebhook {
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub avatar: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub channel_id: Option<ChannelId>,
}
impl ModifyWebhook {
pub fn new() -> Self {
Self::default()
}
pub fn name(mut self, name: impl Into<String>) -> Self {
self.name = Some(name.into());
self
}
pub fn channel_id(mut self, id: ChannelId) -> Self {
self.channel_id = Some(id);
self
}
}
#[derive(Debug, Default, Serialize)]
pub struct ExecuteWebhook {
#[serde(skip_serializing_if = "Option::is_none")]
pub content: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub username: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub avatar_url: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tts: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub embeds: Option<Vec<Embed>>,
}
impl ExecuteWebhook {
pub fn new() -> Self {
Self::default()
}
pub fn content(mut self, content: impl Into<String>) -> Self {
self.content = Some(content.into());
self
}
pub fn username(mut self, name: impl Into<String>) -> Self {
self.username = Some(name.into());
self
}
pub fn avatar_url(mut self, url: impl Into<String>) -> Self {
self.avatar_url = Some(url.into());
self
}
pub fn tts(mut self, tts: bool) -> Self {
self.tts = Some(tts);
self
}
pub fn embed(
mut self,
build: impl FnOnce(
crate::http::endpoints::messages::EmbedBuilder,
) -> crate::http::endpoints::messages::EmbedBuilder,
) -> Self {
let embed = build(crate::http::endpoints::messages::EmbedBuilder::new()).build();
self.embeds.get_or_insert_with(Vec::new).push(embed);
self
}
}
impl HttpClient {
pub async fn create_webhook(
&self,
channel_id: ChannelId,
params: &CreateWebhook,
) -> Result<Webhook, HttpError> {
self.request(Route::CreateWebhook { channel_id }, Some(params))
.await
}
pub async fn get_channel_webhooks(
&self,
channel_id: ChannelId,
) -> Result<Vec<Webhook>, HttpError> {
self.request_no_body(Route::GetChannelWebhooks { channel_id })
.await
}
pub async fn get_guild_webhooks(&self, guild_id: GuildId) -> Result<Vec<Webhook>, HttpError> {
self.request_no_body(Route::GetGuildWebhooks { guild_id })
.await
}
pub async fn get_webhook(&self, webhook_id: &str) -> Result<Webhook, HttpError> {
self.request_no_body(Route::GetWebhook {
webhook_id: webhook_id.to_string(),
})
.await
}
pub async fn modify_webhook(
&self,
webhook_id: &str,
params: &ModifyWebhook,
) -> Result<Webhook, HttpError> {
self.request(
Route::ModifyWebhook {
webhook_id: webhook_id.to_string(),
},
Some(params),
)
.await
}
pub async fn delete_webhook(&self, webhook_id: &str) -> Result<(), HttpError> {
self.request_empty(
Route::DeleteWebhook {
webhook_id: webhook_id.to_string(),
},
None::<&()>,
)
.await
}
pub async fn execute_webhook(
&self,
webhook_id: &str,
webhook_token: &str,
params: &ExecuteWebhook,
) -> Result<Option<Message>, HttpError> {
self.request(
Route::ExecuteWebhook {
webhook_id: webhook_id.to_string(),
webhook_token: webhook_token.to_string(),
},
Some(params),
)
.await
}
pub async fn get_webhook_with_token(
&self,
webhook_id: &str,
webhook_token: &str,
) -> Result<Webhook, HttpError> {
self.request_no_body(Route::GetWebhookWithToken {
webhook_id: webhook_id.to_string(),
webhook_token: webhook_token.to_string(),
})
.await
}
pub async fn update_webhook_with_token(
&self,
webhook_id: &str,
webhook_token: &str,
params: &ModifyWebhook,
) -> Result<Webhook, HttpError> {
self.request(
Route::UpdateWebhookWithToken {
webhook_id: webhook_id.to_string(),
webhook_token: webhook_token.to_string(),
},
Some(params),
)
.await
}
pub async fn delete_webhook_with_token(
&self,
webhook_id: &str,
webhook_token: &str,
) -> Result<(), HttpError> {
self.request_empty(
Route::DeleteWebhookWithToken {
webhook_id: webhook_id.to_string(),
webhook_token: webhook_token.to_string(),
},
None::<&()>,
)
.await
}
pub async fn execute_github_webhook(
&self,
webhook_id: &str,
webhook_token: &str,
body: &impl Serialize,
) -> Result<(), HttpError> {
self.request_empty(
Route::ExecuteGithubWebhook {
webhook_id: webhook_id.to_string(),
webhook_token: webhook_token.to_string(),
},
Some(body),
)
.await
}
pub async fn execute_sentry_webhook(
&self,
webhook_id: &str,
webhook_token: &str,
body: &impl Serialize,
) -> Result<(), HttpError> {
self.request_empty(
Route::ExecuteSentryWebhook {
webhook_id: webhook_id.to_string(),
webhook_token: webhook_token.to_string(),
},
Some(body),
)
.await
}
pub async fn execute_slack_webhook(
&self,
webhook_id: &str,
webhook_token: &str,
body: &impl Serialize,
) -> Result<(), HttpError> {
self.request_empty(
Route::ExecuteSlackWebhook {
webhook_id: webhook_id.to_string(),
webhook_token: webhook_token.to_string(),
},
Some(body),
)
.await
}
}