extern crate reqwest; extern crate rocket; pub mod discord { static API: &str = "https://discord.com/api/v10"; use rocket::serde::{Deserialize, Serialize}; use std::error::Error; use urlencoding::encode; #[derive(Deserialize, Serialize)] pub struct TokenResponse { pub access_token: String, pub token_type: String, pub expires_in: usize, pub refresh_token: String, pub scope: String, } #[derive(Deserialize, Serialize, Clone, Debug)] pub struct AvatarDecorationData { asset: String, sku_id: String, } #[derive(Deserialize, Serialize, Clone, Debug)] #[serde(crate = "rocket::serde")] pub struct User { pub id: String, pub username: String, pub discriminator: String, pub global_name: Option, pub avatar: Option, pub bot: Option, pub system: Option, pub mfa_enabled: Option, pub banner: Option, pub accent_color: Option, pub locale: Option, pub verified: Option, pub email: Option, pub flags: Option, pub premium_type: Option, pub public_flags: Option, pub avatar_decoration_data: Option, } pub struct Client { redirect_uri: String, client_secret: String, client_id: String, } impl Client { pub fn new(redirect_uri: String, client_id: String, client_secret: String) -> Self { Client { redirect_uri, client_id, client_secret, } } pub fn generate_authorize_url(&self, scope: &str, response_type: &str) -> String { let AUTHORIZE_ENDPOINT = "https://discord.com/oauth2/authorize"; format!( "{}?client_id={}&response_type={}&redirect_uri={}&scope={}", AUTHORIZE_ENDPOINT, self.client_id, response_type, &encode(&self.redirect_uri), scope ) } pub async fn get_user( &self, token_response: &TokenResponse, ) -> Result> { let http_client = reqwest::Client::new(); let user_request = http_client .get(format!("{}/{}", API, "users/@me")) .bearer_auth(&token_response.access_token) .send() .await?; let res: User = user_request.json().await?; Ok(res) } pub async fn exchange_code(&self, code: &String) -> Result> { let http_client = reqwest::Client::new(); let exchange_request = http_client .post(format!("{}/{}", API, "/oauth2/token")) .header("content-type", "application/x-www-form-urlencoded") .basic_auth(&self.client_id, Some(&self.client_secret)) .form(&[ ("grant_type", "authorization_code"), ("code", code), ("redirect_uri", &self.redirect_uri), ]) .send() .await?; let res: TokenResponse = exchange_request.json().await?; Ok(res) } } }