Compare commits
4 Commits
0a1c51dddd
...
926f89e1cf
Author | SHA1 | Date |
---|---|---|
kozabrada123 | 926f89e1cf | |
kozabrada123 | 80c99753c4 | |
kozabrada123 | 1fa84b4b63 | |
kozabrada123 | e6a4cc30a6 |
|
@ -12,8 +12,7 @@ use crate::{
|
||||||
instance::{ChorusUser, Instance},
|
instance::{ChorusUser, Instance},
|
||||||
ratelimiter::ChorusRequest,
|
ratelimiter::ChorusRequest,
|
||||||
types::{
|
types::{
|
||||||
DeleteDisableUserSchema, LimitType, PublicUser, Snowflake, User, UserModifyProfileSchema,
|
DeleteDisableUserSchema, GetPomeloEligibilityReturn, GetPomeloSuggestionsReturn, GetUserProfileSchema, LimitType, PublicUser, Snowflake, User, UserModifyProfileSchema, UserModifySchema, UserProfile, UserProfileMetadata, UserSettings, VerifyUserEmailChangeResponse, VerifyUserEmailChangeSchema
|
||||||
UserModifySchema, UserProfile, UserProfileMetadata, UserSettings, VerifyUserEmailChangeResponse, VerifyUserEmailChangeSchema,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -44,6 +43,11 @@ impl ChorusUser {
|
||||||
///
|
///
|
||||||
/// As of 2024/07/28, Spacebar does not yet implement this endpoint.
|
/// As of 2024/07/28, Spacebar does not yet implement this endpoint.
|
||||||
///
|
///
|
||||||
|
/// If fetching with a pomelo username, discriminator should be set to None.
|
||||||
|
///
|
||||||
|
/// This route also permits fetching users with their old pre-pomelo username#discriminator
|
||||||
|
/// combo.
|
||||||
|
///
|
||||||
/// Note:
|
/// Note:
|
||||||
///
|
///
|
||||||
/// "Unless the target user is a bot, you must be able to add
|
/// "Unless the target user is a bot, you must be able to add
|
||||||
|
@ -56,8 +60,12 @@ impl ChorusUser {
|
||||||
///
|
///
|
||||||
/// # Reference
|
/// # Reference
|
||||||
/// See <https://docs.discord.sex/resources/user#get-user-by-username>
|
/// See <https://docs.discord.sex/resources/user#get-user-by-username>
|
||||||
pub async fn get_user_by_username(&mut self, username: &String) -> ChorusResult<PublicUser> {
|
pub async fn get_user_by_username(
|
||||||
User::get_by_username(self, username).await
|
&mut self,
|
||||||
|
username: &String,
|
||||||
|
discriminator: Option<&String>,
|
||||||
|
) -> ChorusResult<PublicUser> {
|
||||||
|
User::get_by_username(self, username, discriminator).await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the user's settings.
|
/// Gets the user's settings.
|
||||||
|
@ -164,8 +172,12 @@ impl ChorusUser {
|
||||||
///
|
///
|
||||||
/// # Reference
|
/// # Reference
|
||||||
/// See <https://docs.discord.sex/resources/user#get-user-profile>
|
/// See <https://docs.discord.sex/resources/user#get-user-profile>
|
||||||
pub async fn get_user_profile(&mut self, id: Snowflake) -> ChorusResult<UserProfile> {
|
pub async fn get_user_profile(
|
||||||
User::get_profile(self, id).await
|
&mut self,
|
||||||
|
id: Snowflake,
|
||||||
|
query_parameters: GetUserProfileSchema,
|
||||||
|
) -> ChorusResult<UserProfile> {
|
||||||
|
User::get_profile(self, id, query_parameters).await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Modifies the current user's profile.
|
/// Modifies the current user's profile.
|
||||||
|
@ -215,7 +227,10 @@ impl ChorusUser {
|
||||||
///
|
///
|
||||||
/// # Reference
|
/// # Reference
|
||||||
/// See <https://docs.discord.sex/resources/user#modify-user-email>
|
/// See <https://docs.discord.sex/resources/user#modify-user-email>
|
||||||
pub async fn verify_email_change(&mut self, schema: VerifyUserEmailChangeSchema) -> ChorusResult<VerifyUserEmailChangeResponse> {
|
pub async fn verify_email_change(
|
||||||
|
&mut self,
|
||||||
|
schema: VerifyUserEmailChangeSchema,
|
||||||
|
) -> ChorusResult<VerifyUserEmailChangeResponse> {
|
||||||
let request = Client::new()
|
let request = Client::new()
|
||||||
.post(format!(
|
.post(format!(
|
||||||
"{}/users/@me/email/verify-code",
|
"{}/users/@me/email/verify-code",
|
||||||
|
@ -227,7 +242,65 @@ impl ChorusUser {
|
||||||
request,
|
request,
|
||||||
limit_type: LimitType::default(),
|
limit_type: LimitType::default(),
|
||||||
};
|
};
|
||||||
chorus_request.deserialize_response::<VerifyUserEmailChangeResponse>(self).await
|
chorus_request
|
||||||
|
.deserialize_response::<VerifyUserEmailChangeResponse>(self)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a suggested unique username based on the current user's username.
|
||||||
|
///
|
||||||
|
/// Note:
|
||||||
|
///
|
||||||
|
/// "This endpoint is used during the pomelo migration flow.
|
||||||
|
///
|
||||||
|
/// The user must be in the rollout to use this endpoint."
|
||||||
|
///
|
||||||
|
/// If a user has already migrated, this endpoint will likely return a 401 Unauthorized
|
||||||
|
/// ([ChorusError::NoPermission])
|
||||||
|
///
|
||||||
|
/// See <https://docs.discord.sex/resources/user#get-pomelo-suggestions>
|
||||||
|
pub async fn get_pomelo_suggestions(&mut self) -> ChorusResult<String> {
|
||||||
|
let request = Client::new()
|
||||||
|
.get(format!(
|
||||||
|
"{}/users/@me/pomelo-suggestions",
|
||||||
|
self.belongs_to.read().unwrap().urls.api
|
||||||
|
))
|
||||||
|
.header("Authorization", self.token());
|
||||||
|
|
||||||
|
let chorus_request = ChorusRequest {
|
||||||
|
request,
|
||||||
|
limit_type: LimitType::default(),
|
||||||
|
};
|
||||||
|
chorus_request
|
||||||
|
.deserialize_response::<GetPomeloSuggestionsReturn>(self)
|
||||||
|
.await
|
||||||
|
.map(|returned| returned.username)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Checks whether a unique username is available.
|
||||||
|
///
|
||||||
|
/// Returns whether the username is not taken yet.
|
||||||
|
///
|
||||||
|
/// See <https://docs.discord.sex/resources/user#get-pomelo-eligibility>
|
||||||
|
pub async fn get_pomelo_eligibility(&mut self, username: &String) -> ChorusResult<bool> {
|
||||||
|
let request = Client::new()
|
||||||
|
.post(format!(
|
||||||
|
"{}/users/@me/pomelo-attempt",
|
||||||
|
self.belongs_to.read().unwrap().urls.api
|
||||||
|
))
|
||||||
|
.header("Authorization", self.token())
|
||||||
|
// FIXME: should we create a type for this?
|
||||||
|
.body(format!(r#"{{ "username": {:?} }}"#, username))
|
||||||
|
.header("Content-Type", "application/json");
|
||||||
|
|
||||||
|
let chorus_request = ChorusRequest {
|
||||||
|
request,
|
||||||
|
limit_type: LimitType::default(),
|
||||||
|
};
|
||||||
|
chorus_request
|
||||||
|
.deserialize_response::<GetPomeloEligibilityReturn>(self)
|
||||||
|
.await
|
||||||
|
.map(|returned| !returned.taken)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,6 +345,11 @@ impl User {
|
||||||
///
|
///
|
||||||
/// As of 2024/07/28, Spacebar does not yet implement this endpoint.
|
/// As of 2024/07/28, Spacebar does not yet implement this endpoint.
|
||||||
///
|
///
|
||||||
|
/// If fetching with a pomelo username, discriminator should be set to None.
|
||||||
|
///
|
||||||
|
/// This route also permits fetching users with their old pre-pomelo username#discriminator
|
||||||
|
/// combo.
|
||||||
|
///
|
||||||
/// Note:
|
/// Note:
|
||||||
///
|
///
|
||||||
/// "Unless the target user is a bot, you must be able to add
|
/// "Unless the target user is a bot, you must be able to add
|
||||||
|
@ -284,12 +362,18 @@ impl User {
|
||||||
pub async fn get_by_username(
|
pub async fn get_by_username(
|
||||||
user: &mut ChorusUser,
|
user: &mut ChorusUser,
|
||||||
username: &String,
|
username: &String,
|
||||||
|
discriminator: Option<&String>,
|
||||||
) -> ChorusResult<PublicUser> {
|
) -> ChorusResult<PublicUser> {
|
||||||
let url_api = user.belongs_to.read().unwrap().urls.api.clone();
|
let url_api = user.belongs_to.read().unwrap().urls.api.clone();
|
||||||
let url = format!("{}/users/username/{username}", url_api);
|
let url = format!("{}/users/username/{username}", url_api);
|
||||||
let request = reqwest::Client::new()
|
let mut request = reqwest::Client::new()
|
||||||
.get(url)
|
.get(url)
|
||||||
.header("Authorization", user.token());
|
.header("Authorization", user.token());
|
||||||
|
|
||||||
|
if let Some(some_discriminator) = discriminator {
|
||||||
|
request = request.query(&[("discriminator", some_discriminator)]);
|
||||||
|
}
|
||||||
|
|
||||||
let chorus_request = ChorusRequest {
|
let chorus_request = ChorusRequest {
|
||||||
request,
|
request,
|
||||||
limit_type: LimitType::Global,
|
limit_type: LimitType::Global,
|
||||||
|
@ -329,12 +413,17 @@ impl User {
|
||||||
///
|
///
|
||||||
/// # Reference
|
/// # Reference
|
||||||
/// See <https://docs.discord.sex/resources/user#get-user-profile>
|
/// See <https://docs.discord.sex/resources/user#get-user-profile>
|
||||||
// TODO: Implement query string parameters for this endpoint
|
pub async fn get_profile(
|
||||||
pub async fn get_profile(user: &mut ChorusUser, id: Snowflake) -> ChorusResult<UserProfile> {
|
user: &mut ChorusUser,
|
||||||
|
id: Snowflake,
|
||||||
|
query_parameters: GetUserProfileSchema,
|
||||||
|
) -> ChorusResult<UserProfile> {
|
||||||
let url_api = user.belongs_to.read().unwrap().urls.api.clone();
|
let url_api = user.belongs_to.read().unwrap().urls.api.clone();
|
||||||
let request: reqwest::RequestBuilder = Client::new()
|
let request: reqwest::RequestBuilder = Client::new()
|
||||||
.get(format!("{}/users/{}/profile", url_api, id))
|
.get(format!("{}/users/{}/profile", url_api, id))
|
||||||
.header("Authorization", user.token());
|
.header("Authorization", user.token())
|
||||||
|
.query(&query_parameters);
|
||||||
|
|
||||||
let chorus_request = ChorusRequest {
|
let chorus_request = ChorusRequest {
|
||||||
request,
|
request,
|
||||||
limit_type: LimitType::Global,
|
limit_type: LimitType::Global,
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use serde_repr::{Deserialize_repr, Serialize_repr};
|
||||||
|
|
||||||
use crate::types::{
|
use crate::types::{
|
||||||
entities::{Application, User},
|
entities::{Application, User},
|
||||||
|
@ -23,7 +24,7 @@ pub struct Integration {
|
||||||
pub syncing: Option<bool>,
|
pub syncing: Option<bool>,
|
||||||
pub role_id: Option<String>,
|
pub role_id: Option<String>,
|
||||||
pub enabled_emoticons: Option<bool>,
|
pub enabled_emoticons: Option<bool>,
|
||||||
pub expire_behaviour: Option<u8>,
|
pub expire_behaviour: Option<IntegrationExpireBehaviour>,
|
||||||
pub expire_grace_period: Option<u16>,
|
pub expire_grace_period: Option<u16>,
|
||||||
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
#[cfg_attr(feature = "sqlx", sqlx(skip))]
|
||||||
pub user: Option<Shared<User>>,
|
pub user: Option<Shared<User>>,
|
||||||
|
@ -50,6 +51,7 @@ pub struct IntegrationAccount {
|
||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
#[cfg_attr(feature = "sqlx", derive(sqlx::Type))]
|
#[cfg_attr(feature = "sqlx", derive(sqlx::Type))]
|
||||||
#[cfg_attr(feature = "sqlx", sqlx(rename_all = "snake_case"))]
|
#[cfg_attr(feature = "sqlx", sqlx(rename_all = "snake_case"))]
|
||||||
|
/// See <https://docs.discord.sex/resources/integration#integration-type>
|
||||||
pub enum IntegrationType {
|
pub enum IntegrationType {
|
||||||
#[default]
|
#[default]
|
||||||
Twitch,
|
Twitch,
|
||||||
|
@ -57,3 +59,32 @@ pub enum IntegrationType {
|
||||||
Discord,
|
Discord,
|
||||||
GuildSubscription,
|
GuildSubscription,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(
|
||||||
|
Serialize_repr,
|
||||||
|
Deserialize_repr,
|
||||||
|
Debug,
|
||||||
|
Default,
|
||||||
|
Clone,
|
||||||
|
Eq,
|
||||||
|
PartialEq,
|
||||||
|
Hash,
|
||||||
|
Copy,
|
||||||
|
PartialOrd,
|
||||||
|
Ord,
|
||||||
|
)]
|
||||||
|
#[cfg_attr(feature = "sqlx", derive(sqlx::Type))]
|
||||||
|
#[repr(u8)]
|
||||||
|
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
|
||||||
|
/// Defines the behaviour that is executed when a user's subscription to the integration expires.
|
||||||
|
///
|
||||||
|
/// See <https://docs.discord.sex/resources/integration#integration-expire-behavior>
|
||||||
|
pub enum IntegrationExpireBehaviour {
|
||||||
|
#[default]
|
||||||
|
/// Remove the subscriber role from the user
|
||||||
|
RemoveRole = 0,
|
||||||
|
/// Kick the user from the guild
|
||||||
|
Kick = 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -181,3 +181,50 @@ pub struct VerifyUserEmailChangeResponse {
|
||||||
#[serde(rename = "token")]
|
#[serde(rename = "token")]
|
||||||
pub email_token: String,
|
pub email_token: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Deserialize, Serialize, Clone, Copy, PartialEq, Eq)]
|
||||||
|
/// Query string parameters for the route GET /users/{user.id}/profile
|
||||||
|
/// ([crate::types::User::get_profile])
|
||||||
|
///
|
||||||
|
/// See <https://docs.discord.sex/resources/user#get-user-profile>
|
||||||
|
pub struct GetUserProfileSchema {
|
||||||
|
/// Whether to include the mutual guilds between the current user.
|
||||||
|
///
|
||||||
|
/// If unset it will default to true
|
||||||
|
pub with_mutual_guilds: Option<bool>,
|
||||||
|
/// Whether to include the mutual friends between the current user.
|
||||||
|
///
|
||||||
|
/// If unset it will default to false
|
||||||
|
pub with_mutual_friends: Option<bool>,
|
||||||
|
/// Whether to include the number of mutual friends between the current user
|
||||||
|
///
|
||||||
|
/// If unset it will default to false
|
||||||
|
pub with_mutual_friends_count: Option<bool>,
|
||||||
|
/// The guild id to get the user's member profile in, if any.
|
||||||
|
///
|
||||||
|
/// Note:
|
||||||
|
///
|
||||||
|
/// when you click on a user in the member list in the discord client, a request is sent with
|
||||||
|
/// this property set to the selected guild id.
|
||||||
|
///
|
||||||
|
/// This makes the request include fields such as guild_member and guild_member_profile
|
||||||
|
pub guild_id: Option<Snowflake>,
|
||||||
|
/// The role id to get the user's application role connection metadata in, if any.
|
||||||
|
pub connections_role_id: Option<Snowflake>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
|
||||||
|
/// Internal type for the [crate::instance::ChorusUser::get_pomelo_suggestions] endpoint.
|
||||||
|
///
|
||||||
|
/// See <https://docs.discord.sex/resources/user#get-pomelo-suggestions>
|
||||||
|
pub(crate) struct GetPomeloSuggestionsReturn {
|
||||||
|
pub username: String
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
|
||||||
|
/// Internal type for the [crate::instance::ChorusUser::get_pomelo_eligibility] endpoint.
|
||||||
|
///
|
||||||
|
/// See <https://docs.discord.sex/resources/user#get-pomelo-eligibility>
|
||||||
|
pub(crate) struct GetPomeloEligibilityReturn {
|
||||||
|
pub taken: bool
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue