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 crate::{
|
||||
errors::ChorusResult,
|
||||
errors::{ChorusError, ChorusResult},
|
||||
instance::ChorusUser,
|
||||
ratelimiter::ChorusRequest,
|
||||
types::{
|
||||
AuthorizeConnectionReturn, AuthorizeConnectionSchema, Connection, ConnectionSubreddit,
|
||||
ConnectionType, CreateConnectionCallbackSchema, CreateContactSyncConnectionSchema,
|
||||
GetConnectionAccessTokenReturn, LimitType, ModifyConnectionSchema,
|
||||
CreateDomainConnectionError, CreateDomainConnectionReturn, GetConnectionAccessTokenReturn,
|
||||
LimitType, ModifyConnectionSchema,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -121,6 +122,92 @@ impl ChorusUser {
|
|||
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>)
|
||||
// It requires changing how chorus handles errors to support properly
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ use chrono::NaiveDate;
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::types::{
|
||||
GuildAffinity, HarvestBackendType, Snowflake, ThemeColors, TwoWayLinkType, UserAffinity,
|
||||
Connection, GuildAffinity, HarvestBackendType, Snowflake, ThemeColors, TwoWayLinkType, UserAffinity
|
||||
};
|
||||
|
||||
#[derive(Debug, Default, Deserialize, Serialize, Clone, PartialEq, Eq)]
|
||||
|
@ -395,3 +395,43 @@ pub struct UserAffinities {
|
|||
pub struct GuildAffinities {
|
||||
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