use http::header::USER_AGENT;
use oauth2::reqwest::async_http_client;
use oauth2::{AuthorizationCode, TokenResponse};
use crate::Result;
use crate::{Config, Database};
use super::UserInfo;
pub const AUTH_URL: &str = "https://discordapp.com/api/oauth2/authorize";
pub const TOKEN_URL: &str = "https://discordapp.com/api/oauth2/token";
#[derive(Clone, Debug, Default, Deserialize)]
#[serde(default)]
struct DiscordUserInfo {
username: String,
avatar: String,
bot: bool,
verified: bool,
email: String,
id: String,
}
impl Into<UserInfo> for DiscordUserInfo {
fn into(self) -> UserInfo {
UserInfo {
email: self.email,
full_name: None,
handle: Some(self.username),
avatar_url: Some(format!(
"https://cdn.discordapp.com/avatars/{}/{}.png?size=160",
self.id, self.avatar
)),
..Default::default()
}
}
}
pub async fn get_user_info<'c>(
auth_code: String,
config: &Config,
db: &Database,
) -> Result<UserInfo> {
let client = crate::oauth::client(
&config.oauth.facebook,
config.domain.clone(),
"discord".to_string(),
AUTH_URL.to_string(),
TOKEN_URL.to_string(),
)?;
let token = client
.exchange_code(AuthorizationCode::new(auth_code.clone()))
.request_async(async_http_client)
.await
.unwrap();
let client = reqwest::Client::new();
let user_info = client
.get("https://discord.com/api/users/@me")
.bearer_auth(token.access_token().secret())
.header(USER_AGENT, format!("{}", config.domain))
.send()
.await?
.json::<DiscordUserInfo>()
.await?;
println!("user_info: {:?}", user_info);
Ok(user_info.into())
}