stat_summoner/
riot_api.rs

1use crate::models::error::Error;
2use reqwest::Client;
3use serde_json::Value;
4use std::collections::HashMap;
5
6/// ⚙️ **Function**: Fetches the player's PUUID (Player Unique Identifier) from the Riot API.
7///
8/// This function sends a request to the Riot API to retrieve the PUUID of a player based on their in-game name and tag line.
9/// The PUUID is a globally unique identifier used across Riot's systems to identify players.
10///
11/// # Parameters:
12/// - `client`: An instance of the `reqwest::Client` used to send HTTP requests.
13/// - `game_name_space`: The player's in-game name (spaces should be replaced with `%20`).
14/// - `tag_line`: The player's tag line, typically a four-digit number associated with their Riot account.
15/// - `riot_api_key`: The API key used to authenticate the request with the Riot API.
16///
17/// # Returns:
18/// - `Result<String, Error>`: The PUUID as a string if the request is successful, or an error if the player does not exist or the request fails.
19///
20/// # ⚠️ Notes:
21/// - If the player does not exist or the information provided is incorrect, the function will return an error message.
22/// - The PUUID is a critical identifier that is used in subsequent requests to fetch match and player data.
23///
24/// # Example:
25/// ```rust
26/// let puuid = get_puuid(&client, "Faker", "1234", riot_api_key).await?;
27/// ```
28///
29/// The resulting `puuid` will be a unique string identifier, such as:
30/// ```text
31/// "abcd1234-efgh5678-ijkl91011-mnop1213"
32/// ```
33pub async fn get_puuid(
34    client: &Client,
35    game_name_space: &str,
36    tag_line: &str,
37    riot_api_key: &str,
38) -> Result<String, Error> {
39    let puuid_url = format!(
40        "https://europe.api.riotgames.com/riot/account/v1/accounts/by-riot-id/{}/{}?api_key={}",
41        game_name_space, tag_line, riot_api_key
42    );
43
44    let response = client.get(&puuid_url).send().await?;
45    let puuid_json: Value = response.json().await?;
46    let puuid = puuid_json
47        .get("puuid")
48        .and_then(Value::as_str)
49        .unwrap_or("")
50        .to_string();
51
52    if puuid.is_empty() {
53        Err("The player could not be found. Please verify that the region, game name, and tag line you provided are correct, and try again.".into())
54    } else {
55        Ok(puuid)
56    }
57}
58
59/// ⚙️ **Function**: Retrieves recent match IDs for a given player using their PUUID.
60///
61/// This function sends a request to the Riot API to fetch the IDs of the player's recent matches based on their PUUID.
62/// The match IDs are used to fetch detailed match data in subsequent API requests.
63///
64/// # Parameters:
65/// - `client`: An instance of the `reqwest::Client` used to send HTTP requests.
66/// - `puuid`: The player's unique PUUID (Player Unique Identifier), used to identify them across Riot's services.
67/// - `riot_api_key`: The API key used to authenticate the request with the Riot API.
68/// - `nb_match`: The number of recent matches to retrieve.
69///
70/// # Returns:
71/// - `Result<Vec<String>, Error>`: A vector containing the IDs of the player's recent matches, or an error if the request fails.
72///
73/// # ⚠️ Notes:
74/// - The function retrieves the most recent 5 matches by default. This can be adjusted in the API URL if necessary.
75/// - Each match ID is a unique string that can be used to query detailed match information.
76/// - The `puuid` must be valid for the request to return match IDs successfully.
77///
78/// # Example:
79/// ```rust
80/// let match_ids = get_matchs_id(&client, "abcd1234-efgh5678-ijkl91011-mnop1213", riot_api_key, 5).await?;
81/// ```
82///
83/// The resulting `match_ids` will be a vector of strings, such as:
84/// ```text
85/// ["EUW1_1234567890", "EUW1_0987654321", "EUW1_2345678901"]
86/// ```
87pub async fn get_matchs_id(
88    client: &Client,
89    puuid: &str,
90    riot_api_key: &str,
91    nb_match: u32,
92) -> Result<Vec<String>, Error> {
93    let matchs_url = format!(
94            "https://europe.api.riotgames.com/lol/match/v5/matches/by-puuid/{}/ids?&count={}&api_key={}",
95            puuid, nb_match.to_string(),  riot_api_key
96        );
97
98    let response = client.get(&matchs_url).send().await?;
99    let matchs_id: Vec<String> = response.json().await?;
100    Ok(matchs_id)
101}
102
103/// ⚙️ **Function**: Fetches ranked information for a player using their summoner ID.
104///
105/// This function sends a request to the Riot API to retrieve ranked information for a player, including their rank,
106/// division, league points (LP), wins, and losses in different game modes (e.g., Solo/Duo, Flex).
107///
108/// # Parameters:
109/// - `client`: An instance of the `reqwest::Client` used to send HTTP requests.
110/// - `region_str`: A string representing the region (e.g., `euw1`, `na1`, `kr`) where the player's account is located.
111/// - `summoner_id`: The unique summoner ID of the player, used to identify them in the ranked ladder.
112/// - `riot_api_key`: The API key used to authenticate the request with the Riot API.
113///
114/// # Returns:
115/// - `Result<Vec<HashMap<String, Value>>, Error>`: A vector of `HashMap` objects containing ranked information for each game mode (Solo/Duo, Flex) or an error if the request fails.
116///
117/// # ⚠️ Notes:
118/// - The returned ranked information includes game modes like Solo/Duo and Flex, along with details such as tier, rank, LP, wins, and losses.
119/// - The function returns an empty vector if no ranked data is found for the player in the specified region.
120///
121/// # Example:
122/// ```rust
123/// let rank_info = get_rank_info(&client, "euw1", "abcdef1234567890abcdef1234567890", riot_api_key).await?;
124/// ```
125///
126/// The resulting `rank_info` will contain ranked data for different game modes, such as:
127/// ```json
128/// [
129///   {
130///     "queueType": "RANKED_SOLO_5x5",
131///     "tier": "Gold",
132///     "rank": "IV",
133///     "leaguePoints": 50,
134///     "wins": 30,
135///     "losses": 20
136///   },
137///   {
138///     "queueType": "RANKED_FLEX_SR",
139///     "tier": "Silver",
140///     "rank": "II",
141///     "leaguePoints": 75,
142///     "wins": 15,
143///     "losses": 10
144///   }
145/// ]
146/// ```
147pub async fn get_rank_info(
148    client: &Client,
149    region_str: &str,
150    summoner_id: &str,
151    riot_api_key: &str,
152) -> Result<Vec<HashMap<String, Value>>, Error> {
153    let rank_url = format!(
154        "https://{}.api.riotgames.com/lol/league/v4/entries/by-puuid/{}?api_key={}",
155        region_str, summoner_id, riot_api_key
156    );
157    let response = client.get(&rank_url).send().await?;
158    Ok(response.json().await?)
159}
160
161/// ⚙️ **Function**: Retrieves the top 10 champions for a player based on champion mastery.
162///
163/// This function sends a request to the Riot API to fetch the player's top 10 champions based on their mastery score.
164/// The information returned includes champion mastery level and points for each champion.
165///
166/// # Parameters:
167/// - `client`: An instance of the `reqwest::Client` used to send HTTP requests.
168/// - `puuid`: The player's unique PUUID (Player Unique Identifier), used to identify the player in Riot's systems.
169/// - `region`: A string representing the region (e.g., `euw1`, `na1`, `kr`) where the player's account is located.
170/// - `riot_api_key`: The API key used to authenticate the request with the Riot API.
171///
172/// # Returns:
173/// - `Result<Vec<HashMap<String, Value>>, Error>`: A vector of `HashMap` objects, where each entry contains champion mastery details, or an error if the request fails.
174///
175/// # ⚠️ Notes:
176/// - The function returns the top 10 champions based on mastery points, but this count can be adjusted in the API URL.
177/// - The information includes each champion's ID, mastery level, and mastery points.
178/// - The function requires a valid `puuid` and `region` for the request to succeed.
179///
180/// # Example:
181/// ```rust
182/// let top_champions = get_champions(&client, "abcd1234-efgh5678-ijkl91011-mnop1213", "euw1", riot_api_key).await?;
183/// ```
184///
185/// The resulting `top_champions` vector will contain data like:
186/// ```json
187/// [
188///   {
189///     "championId": 157,
190///     "championLevel": 7,
191///     "championPoints": 500000
192///   },
193///   {
194///     "championId": 238,
195///     "championLevel": 6,
196///     "championPoints": 350000
197///   }
198/// ]
199/// ```
200pub async fn get_champions(
201    client: &Client,
202    puuid: &str,
203    region: &str,
204    riot_api_key: &str,
205) -> Result<Vec<HashMap<String, Value>>, Error> {
206    let champions_url = format!(
207            "https://{}.api.riotgames.com/lol/champion-mastery/v4/champion-masteries/by-puuid/{}/top?count=10&api_key={}",
208            region, puuid, riot_api_key
209        );
210    let response = client.get(&champions_url).send().await?;
211    Ok(response.json().await?)
212}
213
214/// ⚙️ **Function**: Fetches the latest champion data from Data Dragon (Riot's official static data service).
215///
216/// This function sends a request to Data Dragon to retrieve the latest static data about League of Legends champions,
217/// such as champion names, IDs, and related information. The data is returned as a JSON object and can be used to map
218/// champion IDs to their names and other static details.
219///
220/// # Returns:
221/// - `Result<Value, Error>`: A JSON object containing champion data if the request is successful, or an error if the request fails.
222///
223/// # ⚠️ Notes:
224/// - The request fetches champion data in French (`fr_FR`), but the language can be changed by modifying the URL.
225/// - Data Dragon provides static, versioned data, which means this data may not always be up to date with the latest game patches unless the URL version is updated.
226///
227/// # Example:
228/// ```rust
229/// let dd_json = open_dd_json().await?;
230/// ```
231///
232/// The resulting `dd_json` will contain champion data like:
233/// ```json
234/// {
235///   "type": "champion",
236///   "format": "standAloneComplex",
237///   "data": {
238///     "Aatrox": {
239///       "id": "Aatrox",
240///       "key": "266",
241///       "name": "Aatrox",
242///       ...
243///     },
244///     ...
245///   }
246/// }
247/// ```
248pub async fn open_dd_json() -> Result<Value, Error> {
249    let version_json: Value = reqwest::get("https://ddragon.leagueoflegends.com/api/versions.json")
250        .await?
251        .json()
252        .await?;
253    let version = version_json[0].as_str().unwrap();
254    let dd_json = reqwest::get(format!(
255        "https://ddragon.leagueoflegends.com/cdn/{}/data/en_US/champion.json",
256        version
257    ))
258    .await?
259    .json()
260    .await?;
261    log::info!("Data dragon version: {}", version);
262    Ok(dd_json)
263}
264
265/// ⚙️ **Function**: Fetches detailed information about a specific match using the match ID.
266///
267/// This function sends a request to the Riot API to retrieve detailed information about a match, such as
268/// participants, game duration, result (win/loss), and other match-related statistics. The match data is returned
269/// as a JSON object.
270///
271/// # Parameters:
272/// - `client`: An instance of the `reqwest::Client` used to send HTTP requests.
273/// - `match_id`: The unique ID of the match to retrieve. Each match is assigned a unique identifier in the Riot API.
274/// - `riot_api_key`: The API key used to authenticate the request with the Riot API.
275///
276/// # Returns:
277/// - `Result<Value, Error>`: A JSON object containing detailed match data if the request is successful, or an error if the request fails.
278///
279/// # ⚠️ Notes:
280/// - The match data includes detailed statistics for each participant, including champion played, kills, deaths, assists, and more.
281/// - The `match_id` must be valid for the request to succeed; otherwise, the function returns an error.
282///
283/// # Example:
284/// ```rust
285/// let match_info = get_matchs_info(&client, "EUW1_1234567890", riot_api_key).await?;
286/// ```
287///
288/// The resulting `match_info` will contain detailed match data like:
289/// ```json
290/// {
291///   "metadata": {
292///     "dataVersion": "2",
293///     "matchId": "EUW1_1234567890"
294///   },
295///   "info": {
296///     "gameCreation": 1625000000000,
297///     "gameDuration": 1800,
298///     "participants": [
299///       {
300///         "summonerName": "Faker",
301///         "championName": "Yasuo",
302///         "kills": 10,
303///         "deaths": 2,
304///         "assists": 8,
305///         ...
306///       }
307///     ]
308///   }
309/// }
310/// ```
311pub async fn get_matchs_info(
312    client: &Client,
313    match_id: &str,
314    riot_api_key: &str,
315) -> Result<Value, Error> {
316    let matchs_info_url = format!(
317        "https://europe.api.riotgames.com/lol/match/v5/matches/{}?api_key={}",
318        match_id, riot_api_key
319    );
320    eprint!("Fetching match data from {}...\n", matchs_info_url);
321    let response = client.get(&matchs_info_url).send().await?;
322    let matchs_info: Value = response.json().await?;
323    Ok(matchs_info)
324}