twitch_oauth/
lib.rs

1use reqwest::header::AUTHORIZATION;
2use reqwest::Client;
3use reqwest::Url;
4use serde::{Deserialize, Serialize};
5use std::collections::HashMap;
6
7#[derive(Debug, Deserialize, Serialize, Clone)]
8pub struct ValidatedToken {
9    client_id: String,
10    login: Option<String>,
11    user_id: Option<String>,
12    scopes: Vec<String>,
13}
14
15#[derive(Debug, Deserialize, Serialize, Clone)]
16pub struct AppAccessToken {
17    access_token: String,
18    expires_in: usize,
19    scope: Option<Vec<String>>,
20    token_type: String,
21}
22
23pub async fn get_app_access_token(
24    client_id: &str,
25    client_secret: &str,
26    scopes: Vec<String>,
27) -> Result<AppAccessToken, Box<dyn std::error::Error>> {
28    let joinee_scopes = scopes.join(" ");
29
30    let mut params = HashMap::new();
31    params.insert("grant_type", "client_credentials");
32    params.insert("client_id", client_id);
33    params.insert("client_secret", client_secret);
34    params.insert("scope", joinee_scopes.as_str());
35
36    let url = Url::parse_with_params("https://id.twitch.tv/oauth2/token", &params).unwrap();
37
38    let resp: AppAccessToken = Client::new()
39        .post(url)
40        .send()
41        .await?
42        .error_for_status()?
43        .json()
44        .await?;
45
46    Ok(resp)
47}
48
49pub async fn validate_token(
50    token: AppAccessToken,
51) -> Result<ValidatedToken, Box<dyn std::error::Error>> {
52    let auth_header = format!("OAuth {}", token.access_token);
53
54    let resp: ValidatedToken = Client::new()
55        .get("https://id.twitch.tv/oauth2/validate")
56        .header(AUTHORIZATION, auth_header)
57        .send()
58        .await?
59        .error_for_status()?
60        .json()
61        .await?;
62
63    Ok(resp)
64}
65
66pub async fn revoke_token(
67    token: AppAccessToken,
68    client_id: &str,
69) -> Result<(), Box<dyn std::error::Error>> {
70    let mut params = HashMap::new();
71    params.insert("token", token.access_token.as_str());
72    params.insert("client_id", client_id);
73
74    let url = Url::parse_with_params("https://id.twitch.tv/oauth2/revoke", &params).unwrap();
75
76    Client::new().post(url).send().await?.error_for_status()?;
77
78    Ok(())
79}