From 7b55590fd0d830dd7c6f0077dc263e8ce397c3a7 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Fri, 25 Aug 2023 16:47:28 +0200 Subject: [PATCH 1/5] Add modify_member route --- src/api/guilds/guilds.rs | 32 +++++++++++++++++++++++++++++++- src/types/schema/guild.rs | 30 ++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/src/api/guilds/guilds.rs b/src/api/guilds/guilds.rs index e59f3bc..e2fe66b 100644 --- a/src/api/guilds/guilds.rs +++ b/src/api/guilds/guilds.rs @@ -9,7 +9,7 @@ use crate::instance::ChorusUser; use crate::ratelimiter::ChorusRequest; use crate::types::{ Channel, ChannelCreateSchema, Guild, GuildBanCreateSchema, GuildCreateSchema, GuildMember, - GuildMemberSearchSchema, GuildModifySchema, GuildPreview, + GuildMemberSearchSchema, GuildModifySchema, GuildPreview, ModifyGuildMemberSchema, }; use crate::types::{GuildBan, Snowflake}; @@ -295,6 +295,36 @@ impl Guild { ); request.handle_request_as_result(user).await } + + /// Modifies attributes of a guild member. Returns the updated guild member object on success. + /// For required Permissions and an API reference, see: + /// + /// # Reference: + /// + pub async fn modify_member( + guild_id: Snowflake, + member_id: Snowflake, + schema: ModifyGuildMemberSchema, + audit_log_reason: Option, + user: &mut ChorusUser, + ) -> ChorusResult<()> { + let request = ChorusRequest::new( + http::Method::PATCH, + format!( + "{}/guilds/{}/members/{}", + user.belongs_to.borrow().urls.api, + guild_id, + member_id, + ) + .as_str(), + Some(to_string(&schema).unwrap()), + audit_log_reason.as_deref(), + None, + Some(user), + LimitType::Guild(guild_id), + ); + request.handle_request_as_result(user).await + } } impl Channel { diff --git a/src/types/schema/guild.rs b/src/types/schema/guild.rs index 34ced20..72fbdb3 100644 --- a/src/types/schema/guild.rs +++ b/src/types/schema/guild.rs @@ -1,3 +1,5 @@ +use bitflags::bitflags; +use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use crate::types::entities::Channel; @@ -106,3 +108,31 @@ impl Default for GuildMemberSearchSchema { } } } + +#[derive(Debug, Serialize, Deserialize)] +pub struct ModifyGuildMemberSchema { + pub nick: Option, + pub roles: Option>, + pub mute: Option, + pub deaf: Option, + pub channel_id: Option, + pub communication_disabled_until: Option>, + pub flags: Option, +} + +bitflags! { + #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, PartialOrd, Ord)] + /// Represents the flags of a Guild Member. + /// + /// # Reference: + /// See + pub struct GuildMemberFlags: u64 { + const DID_REJOIN = 1 << 0; + const COMPLETED_ONBOARDING = 1 << 1; + const BYPASSES_VERIFICATION = 1 << 2; + const STARTED_ONBOARDING = 1 << 3; + const GUEST = 1 << 3; + const AUTOMOD_QUARANTINED_NAME = 1 << 7; + const AUTOMOD_QUARANTINED_BIO = 1 << 8; + } +} From cce5b507bcff783b97373ed5aee3a0b04f1519bb Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Fri, 25 Aug 2023 16:54:41 +0200 Subject: [PATCH 2/5] Add modify_current_member route --- src/api/guilds/guilds.rs | 31 +++++++++++++++++++++++++++++-- src/types/schema/guild.rs | 10 +++++++++- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/api/guilds/guilds.rs b/src/api/guilds/guilds.rs index e2fe66b..547f3cf 100644 --- a/src/api/guilds/guilds.rs +++ b/src/api/guilds/guilds.rs @@ -307,7 +307,7 @@ impl Guild { schema: ModifyGuildMemberSchema, audit_log_reason: Option, user: &mut ChorusUser, - ) -> ChorusResult<()> { + ) -> ChorusResult { let request = ChorusRequest::new( http::Method::PATCH, format!( @@ -323,7 +323,34 @@ impl Guild { Some(user), LimitType::Guild(guild_id), ); - request.handle_request_as_result(user).await + request.deserialize_response::(user).await + } + + /// Modifies the current user's member in the guild. + /// + /// # Reference: + /// See + pub async fn modify_current_member( + guild_id: Snowflake, + schema: ModifyGuildMemberSchema, + audit_log_reason: Option, + user: &mut ChorusUser, + ) -> ChorusResult { + let request = ChorusRequest::new( + http::Method::PATCH, + format!( + "{}/guilds/{}/members/@me", + user.belongs_to.borrow().urls.api, + guild_id, + ) + .as_str(), + Some(to_string(&schema).unwrap()), + audit_log_reason.as_deref(), + None, + Some(user), + LimitType::Guild(guild_id), + ); + request.deserialize_response::(user).await } } diff --git a/src/types/schema/guild.rs b/src/types/schema/guild.rs index 72fbdb3..3f5dcea 100644 --- a/src/types/schema/guild.rs +++ b/src/types/schema/guild.rs @@ -109,7 +109,7 @@ impl Default for GuildMemberSearchSchema { } } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, PartialOrd, Eq, Ord)] pub struct ModifyGuildMemberSchema { pub nick: Option, pub roles: Option>, @@ -136,3 +136,11 @@ bitflags! { const AUTOMOD_QUARANTINED_BIO = 1 << 8; } } + +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, PartialOrd, Eq, Ord)] +pub struct ModifyCurrentGuildMemberSchema { + pub nick: Option, + pub avatar: Option, + pub bio: Option, + pub banner: Option, +} From cd70a5b388ad069b6a69cf2dff57168a6a18bf2e Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Fri, 25 Aug 2023 17:11:00 +0200 Subject: [PATCH 3/5] Add modify guild member profile route --- src/api/guilds/guilds.rs | 31 ++++++++++++++++++++++++++++++- src/types/entities/user.rs | 14 ++++++++++++++ src/types/schema/guild.rs | 11 +++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/src/api/guilds/guilds.rs b/src/api/guilds/guilds.rs index 547f3cf..59936b4 100644 --- a/src/api/guilds/guilds.rs +++ b/src/api/guilds/guilds.rs @@ -9,7 +9,8 @@ use crate::instance::ChorusUser; use crate::ratelimiter::ChorusRequest; use crate::types::{ Channel, ChannelCreateSchema, Guild, GuildBanCreateSchema, GuildCreateSchema, GuildMember, - GuildMemberSearchSchema, GuildModifySchema, GuildPreview, ModifyGuildMemberSchema, + GuildMemberSearchSchema, GuildModifySchema, GuildPreview, ModifyGuildMemberProfileSchema, + ModifyGuildMemberSchema, UserProfileMetadata, }; use crate::types::{GuildBan, Snowflake}; @@ -352,6 +353,34 @@ impl Guild { ); request.deserialize_response::(user).await } + + /// Modifies the current user's profile in the guild. + /// + /// # Reference: + /// See + pub async fn modify_member_profile( + guild_id: Snowflake, + schema: ModifyGuildMemberProfileSchema, + user: &mut ChorusUser, + ) -> ChorusResult { + let request = ChorusRequest::new( + http::Method::PATCH, + format!( + "{}/guilds/{}/profile/@me", + user.belongs_to.borrow().urls.api, + guild_id, + ) + .as_str(), + Some(to_string(&schema).unwrap()), + None, + None, + Some(user), + LimitType::Guild(guild_id), + ); + request + .deserialize_response::(user) + .await + } } impl Channel { diff --git a/src/types/entities/user.rs b/src/types/entities/user.rs index aadfd35..ed18d2d 100644 --- a/src/types/entities/user.rs +++ b/src/types/entities/user.rs @@ -7,6 +7,8 @@ use std::fmt::Debug; use crate::gateway::{GatewayHandle, Updateable}; use crate::types::{utils::Snowflake, Composite}; +use super::Emoji; + #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)] #[cfg_attr(feature = "sqlx", derive(sqlx::Type))] pub struct UserData { @@ -120,3 +122,15 @@ bitflags::bitflags! { const BOT_HTTP_INTERACTIONS = 1 << 19; } } + +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, PartialOrd, Eq, Ord)] +pub struct UserProfileMetadata { + pub guild_id: Option, + pub pronouns: String, + pub bio: Option, + pub banner: Option, + pub accent_color: Option, + pub theme_colors: Option>, + pub popout_animation_particle_type: Option, + pub emoji: Option, +} diff --git a/src/types/schema/guild.rs b/src/types/schema/guild.rs index 3f5dcea..51fe423 100644 --- a/src/types/schema/guild.rs +++ b/src/types/schema/guild.rs @@ -144,3 +144,14 @@ pub struct ModifyCurrentGuildMemberSchema { pub bio: Option, pub banner: Option, } + +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, PartialOrd, Eq, Ord)] +pub struct ModifyGuildMemberProfileSchema { + pub pronouns: Option, + pub bio: Option, + pub banner: Option, + pub accent_color: Option, + pub theme_colors: Option>, + pub popout_animation_particle_type: Option, + pub emoji_id: Option, +} From 07ebaf6119588b05a47f10665f7b2084d3f03b31 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Fri, 25 Aug 2023 17:26:01 +0200 Subject: [PATCH 4/5] Add Get Guild Ban/s, add audit_log_reason to create_ban --- src/api/guilds/guilds.rs | 96 +++++++++++++++++++++++++++++++------- src/types/entities/user.rs | 2 +- src/types/schema/guild.rs | 8 ++++ tests/guilds.rs | 2 + 4 files changed, 89 insertions(+), 19 deletions(-) diff --git a/src/api/guilds/guilds.rs b/src/api/guilds/guilds.rs index 59936b4..2f0c531 100644 --- a/src/api/guilds/guilds.rs +++ b/src/api/guilds/guilds.rs @@ -8,9 +8,9 @@ use crate::errors::ChorusResult; use crate::instance::ChorusUser; use crate::ratelimiter::ChorusRequest; use crate::types::{ - Channel, ChannelCreateSchema, Guild, GuildBanCreateSchema, GuildCreateSchema, GuildMember, - GuildMemberSearchSchema, GuildModifySchema, GuildPreview, ModifyGuildMemberProfileSchema, - ModifyGuildMemberSchema, UserProfileMetadata, + Channel, ChannelCreateSchema, Guild, GuildBanCreateSchema, GuildBansQuery, GuildCreateSchema, + GuildMember, GuildMemberSearchSchema, GuildModifySchema, GuildPreview, + ModifyGuildMemberProfileSchema, ModifyGuildMemberSchema, UserProfileMetadata, }; use crate::types::{GuildBan, Snowflake}; @@ -146,24 +146,26 @@ impl Guild { pub async fn create_ban( guild_id: Snowflake, user_id: Snowflake, + audit_log_reason: Option, schema: GuildBanCreateSchema, user: &mut ChorusUser, ) -> ChorusResult { - let chorus_request = ChorusRequest { - request: Client::new() - .put(format!( - "{}/guilds/{}/bans/{}", - user.belongs_to.borrow().urls.api, - guild_id, - user_id - )) - .header("Authorization", user.token()) - .body(to_string(&schema).unwrap()), - limit_type: LimitType::Guild(guild_id), - }; - let response = chorus_request - .deserialize_response::(user) - .await?; + let request = ChorusRequest::new( + http::Method::PUT, + format!( + "{}/guilds/{}/bans/{}", + user.belongs_to.borrow().urls.api, + guild_id, + user_id + ) + .as_str(), + Some(to_string(&schema).unwrap()), + audit_log_reason.as_deref(), + None, + Some(user), + LimitType::Guild(guild_id), + ); + let response = request.deserialize_response::(user).await?; Ok(response) } @@ -381,6 +383,64 @@ impl Guild { .deserialize_response::(user) .await } + + /// Returns a list of ban objects for the guild. Requires the `BAN_MEMBERS` permission. + /// + /// # Reference: + /// See + pub async fn get_bans( + user: &mut ChorusUser, + guild_id: Snowflake, + query: Option, + ) -> ChorusResult> { + let url = format!( + "{}/guilds/{}/bans", + user.belongs_to.borrow_mut().urls.api, + guild_id, + ); + + let mut request = ChorusRequest::new( + http::Method::GET, + &url, + None, + None, + None, + Some(user), + LimitType::Guild(guild_id), + ); + if let Some(query) = query { + request.request = request.request.query(&to_string(&query).unwrap()); + } + request.deserialize_response::>(user).await + } + + /// Returns a ban object for the given user. Requires the `BAN_MEMBERS` permission. + /// + /// # Reference: + /// See + pub async fn get_ban( + user: &mut ChorusUser, + guild_id: Snowflake, + user_id: Snowflake, + ) -> ChorusResult { + let url = format!( + "{}/guilds/{}/bans/{}", + user.belongs_to.borrow_mut().urls.api, + guild_id, + user_id + ); + + let request = ChorusRequest::new( + http::Method::GET, + &url, + None, + None, + None, + Some(user), + LimitType::Guild(guild_id), + ); + request.deserialize_response::(user).await + } } impl Channel { diff --git a/src/types/entities/user.rs b/src/types/entities/user.rs index ed18d2d..64334ff 100644 --- a/src/types/entities/user.rs +++ b/src/types/entities/user.rs @@ -123,7 +123,7 @@ bitflags::bitflags! { } } -#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, PartialOrd, Eq, Ord)] +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, PartialOrd)] pub struct UserProfileMetadata { pub guild_id: Option, pub pronouns: String, diff --git a/src/types/schema/guild.rs b/src/types/schema/guild.rs index 51fe423..56c0f9e 100644 --- a/src/types/schema/guild.rs +++ b/src/types/schema/guild.rs @@ -155,3 +155,11 @@ pub struct ModifyGuildMemberProfileSchema { pub popout_animation_particle_type: Option, pub emoji_id: Option, } + +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, PartialOrd, Eq, Ord)] +/// The limit argument is a number between 1 and 1000. +pub struct GuildBansQuery { + pub before: Option, + pub after: Option, + pub limit: Option, +} diff --git a/tests/guilds.rs b/tests/guilds.rs index 8ae6596..c87e68d 100644 --- a/tests/guilds.rs +++ b/tests/guilds.rs @@ -53,6 +53,7 @@ async fn guild_create_ban() { Guild::create_ban( guild.id, other_user_id, + None, GuildBanCreateSchema::default(), &mut bundle.user, ) @@ -61,6 +62,7 @@ async fn guild_create_ban() { assert!(Guild::create_ban( guild.id, other_user_id, + None, GuildBanCreateSchema::default(), &mut bundle.user, ) From 1709e85a4bff31a886ee311cd9ef23f19c3665c9 Mon Sep 17 00:00:00 2001 From: bitfl0wer Date: Fri, 25 Aug 2023 17:28:02 +0200 Subject: [PATCH 5/5] Add delete_guild_ban --- src/api/guilds/guilds.rs | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/api/guilds/guilds.rs b/src/api/guilds/guilds.rs index 2f0c531..0d66686 100644 --- a/src/api/guilds/guilds.rs +++ b/src/api/guilds/guilds.rs @@ -441,6 +441,35 @@ impl Guild { ); request.deserialize_response::(user).await } + + /// Removes the ban for a user. Requires the BAN_MEMBERS permissions. Returns a 204 empty response on success. + /// + /// # Reference: + /// See + pub async fn delete_ban( + user: &mut ChorusUser, + guild_id: Snowflake, + user_id: Snowflake, + audit_log_reason: Option, + ) -> ChorusResult<()> { + let url = format!( + "{}/guilds/{}/bans/{}", + user.belongs_to.borrow_mut().urls.api, + guild_id, + user_id + ); + + let request = ChorusRequest::new( + http::Method::DELETE, + &url, + None, + audit_log_reason.as_deref(), + None, + Some(user), + LimitType::Guild(guild_id), + ); + request.handle_request_as_result(user).await + } } impl Channel {