feat: add create_domain_connection
This commit is contained in:
parent
b7d549756a
commit
2f4198c0a4
|
@ -2,13 +2,14 @@ use futures_util::FutureExt;
|
||||||
use reqwest::Client;
|
use reqwest::Client;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
errors::ChorusResult,
|
errors::{ChorusError, ChorusResult},
|
||||||
instance::ChorusUser,
|
instance::ChorusUser,
|
||||||
ratelimiter::ChorusRequest,
|
ratelimiter::ChorusRequest,
|
||||||
types::{
|
types::{
|
||||||
AuthorizeConnectionReturn, AuthorizeConnectionSchema, Connection, ConnectionSubreddit,
|
AuthorizeConnectionReturn, AuthorizeConnectionSchema, Connection, ConnectionSubreddit,
|
||||||
ConnectionType, CreateConnectionCallbackSchema, CreateContactSyncConnectionSchema,
|
ConnectionType, CreateConnectionCallbackSchema, CreateContactSyncConnectionSchema,
|
||||||
GetConnectionAccessTokenReturn, LimitType, ModifyConnectionSchema,
|
CreateDomainConnectionError, CreateDomainConnectionReturn, GetConnectionAccessTokenReturn,
|
||||||
|
LimitType, ModifyConnectionSchema,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -121,6 +122,92 @@ impl ChorusUser {
|
||||||
chorus_request.deserialize_response(self).await
|
chorus_request.deserialize_response(self).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates a new domain connection for the current user.
|
||||||
|
///
|
||||||
|
/// This route has two possible successful return values:
|
||||||
|
/// [CreateDomainConnectionReturn::Ok] and [CreateDomainConnectionReturn::ProofNeeded]
|
||||||
|
///
|
||||||
|
/// To properly handle both, please see their respective documentation pages.
|
||||||
|
///
|
||||||
|
/// # Notes
|
||||||
|
/// To create normal connection types, see [Self::authorize_connection] and
|
||||||
|
/// [Self::create_connection_callback]
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// ```no_run
|
||||||
|
/// let domain = "example.com".to_string();
|
||||||
|
///
|
||||||
|
/// let result = user.create_domain_connection(&domain).await;
|
||||||
|
///
|
||||||
|
/// if let Ok(returned) = result {
|
||||||
|
/// match returned {
|
||||||
|
/// CreateDomainConnectionReturn::ProofNeeded(proof) => {
|
||||||
|
/// println!("Additional proof needed!");
|
||||||
|
/// println!("Either:");
|
||||||
|
/// println!("");
|
||||||
|
/// println!("- create a DNS TXT record with the name _discord.{domain} and content {proof}");
|
||||||
|
/// println!("or");
|
||||||
|
/// println!("- create a file at https://{domain}/.well-known/discord with the content {proof}");
|
||||||
|
/// // Once the user has added the proof, retry calling the endpoint
|
||||||
|
/// }
|
||||||
|
/// CreateDomainConnectionReturn::Ok(connection) => {
|
||||||
|
/// println!("Successfulyl created connection! {:?}", connection);
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// } else {
|
||||||
|
/// println!("Failed to create connection: {:?}", result);
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// # Reference
|
||||||
|
/// See <https://docs.discord.sex/resources/user#create-domain-connection>
|
||||||
|
pub async fn create_domain_connection(
|
||||||
|
&mut self,
|
||||||
|
domain: &String,
|
||||||
|
) -> ChorusResult<CreateDomainConnectionReturn> {
|
||||||
|
let request = Client::new()
|
||||||
|
.post(format!(
|
||||||
|
"{}/users/@me/connections/domain/{}",
|
||||||
|
self.belongs_to.read().unwrap().urls.api,
|
||||||
|
domain
|
||||||
|
))
|
||||||
|
.header("Authorization", self.token());
|
||||||
|
|
||||||
|
let chorus_request = ChorusRequest {
|
||||||
|
request,
|
||||||
|
limit_type: LimitType::default(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let result = chorus_request
|
||||||
|
.deserialize_response::<Connection>(self)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
if let Ok(connection) = result {
|
||||||
|
return Ok(CreateDomainConnectionReturn::Ok(connection));
|
||||||
|
}
|
||||||
|
|
||||||
|
let error = result.err().unwrap();
|
||||||
|
|
||||||
|
if let ChorusError::ReceivedErrorCode {
|
||||||
|
error_code,
|
||||||
|
error: ref error_string,
|
||||||
|
} = error
|
||||||
|
{
|
||||||
|
if error_code == 400 {
|
||||||
|
let try_deserialize: Result<CreateDomainConnectionError, serde_json::Error> =
|
||||||
|
serde_json::from_str(error_string);
|
||||||
|
|
||||||
|
if let Ok(deserialized_error) = try_deserialize {
|
||||||
|
return Ok(CreateDomainConnectionReturn::ProofNeeded(
|
||||||
|
deserialized_error.proof,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Err(error);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Add create_domain_connection (<https://docs.discord.sex/resources/user#create-domain-connection>)
|
// TODO: Add create_domain_connection (<https://docs.discord.sex/resources/user#create-domain-connection>)
|
||||||
// It requires changing how chorus handles errors to support properly
|
// It requires changing how chorus handles errors to support properly
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ use chrono::NaiveDate;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::types::{
|
use crate::types::{
|
||||||
GuildAffinity, HarvestBackendType, Snowflake, ThemeColors, TwoWayLinkType, UserAffinity,
|
Connection, GuildAffinity, HarvestBackendType, Snowflake, ThemeColors, TwoWayLinkType, UserAffinity
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Default, Deserialize, Serialize, Clone, PartialEq, Eq)]
|
#[derive(Debug, Default, Deserialize, Serialize, Clone, PartialEq, Eq)]
|
||||||
|
@ -395,3 +395,43 @@ pub struct UserAffinities {
|
||||||
pub struct GuildAffinities {
|
pub struct GuildAffinities {
|
||||||
pub guild_affinities: Vec<GuildAffinity>,
|
pub guild_affinities: Vec<GuildAffinity>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
|
||||||
|
/// Return type for the error in the [crate::instance::ChorusUser::create_domain_connection] endpoint.
|
||||||
|
///
|
||||||
|
/// This allows us to retrieve the needed proof for actually verifying the connection.
|
||||||
|
///
|
||||||
|
/// See <https://docs.discord.sex/resources/user#create-domain-connection>
|
||||||
|
pub(crate) struct CreateDomainConnectionError {
|
||||||
|
pub message: String,
|
||||||
|
pub code: u16,
|
||||||
|
pub proof: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
/// Return type for the [crate::instance::ChorusUser::create_domain_connection] endpoint.
|
||||||
|
///
|
||||||
|
/// See <https://docs.discord.sex/resources/user#create-domain-connection>
|
||||||
|
pub enum CreateDomainConnectionReturn {
|
||||||
|
/// Additional proof is needed to verify domain ownership.
|
||||||
|
///
|
||||||
|
/// The inner object is a proof string (e.g.
|
||||||
|
/// `dh=dceaca792e3c40fcf356a9297949940af5cfe538`)
|
||||||
|
///
|
||||||
|
/// To verify ownership, either:
|
||||||
|
///
|
||||||
|
/// - add the proof string as a TXT DNS record to the domain,
|
||||||
|
/// with the name of the record being `_discord.{domain}`
|
||||||
|
///
|
||||||
|
/// or
|
||||||
|
///
|
||||||
|
/// - serve the proof string as a file at `https://{domain}/.well-known/discord`
|
||||||
|
///
|
||||||
|
/// After either of these proofs are added, the request should be retried.
|
||||||
|
///
|
||||||
|
ProofNeeded(String),
|
||||||
|
/// The domain connection was successfully created, no further action is needed.
|
||||||
|
///
|
||||||
|
/// The inner object is the new connection.
|
||||||
|
Ok(Connection)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue