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}