valorant_api/lib.rs
1#![deny(warnings)]
2#![deny(unused)]
3#![deny(clippy::expect_used)]
4#![deny(clippy::get_unwrap)]
5#![deny(clippy::exit)]
6#![deny(clippy::indexing_slicing)]
7#![deny(clippy::panic)]
8#![deny(clippy::panic_in_result_fn)]
9#![deny(clippy::unreachable)]
10#![deny(clippy::unwrap_used)]
11#![deny(clippy::unwrap_in_result)]
12#![deny(clippy::print_stdout)]
13#![allow(clippy::upper_case_acronyms)]
14
15//! # Valorant API
16//! This crate is a wrapper for the In-Game Valorant API.
17//!
18//! ## Usage
19//!
20//! ### 1. Authenticate
21//!
22//! To use this crate, you need to authenticate with your Riot Games account.
23//! Currently, the only way to do this is by using a username and password (no 2FA).
24//!
25//! ```rust no_run
26//! use valorant_api::utils::credentials_manager::CredentialsManager;
27//! use valorant_api::utils::network::http_client::SimpleHttpClient;
28//!
29//! #[tokio::main]
30//! async fn main() {
31//! let http_client = SimpleHttpClient::new();
32//! let mut credentials_manager = valorant_api::utils::credentials_manager::CredentialsManager::new();
33//! let result = credentials_manager
34//! .authenticate(&http_client, "username", "password")
35//! .await;
36//! match result {
37//! Ok(_) => println!("Authenticated"),
38//! Err(_) => println!("Error while authenticating"),
39//! }
40//! }
41//! ```
42//!
43//! ### 2. Use the API
44//!
45//! ```rust no_run
46//! use valorant_api::enums::region::Region;
47//! use uuid::Uuid;
48//! use std::collections::HashMap;
49//!
50//! let puuid = Uuid::parse_str("ee89b4d9-13d0-5832-8dd7-eb5d8806d918").expect("Invalid UUID");
51//! let region = Region::EU;
52//! let queries = HashMap::new();
53//! let result = valorant_api::get_competitve_updates_v1(credentials_manager, &http_client, region, &puuid, queries).await;
54//! println!("Result: {:#?}", result);
55//! ```
56//!
57//! ## Endpoints
58//!
59//! ### Competitive Updates V1
60//!
61//! Function: [`get_competitive_updates_v1`]
62//!
63//! Result Type: [`CompetitiveUpdatesV1`]
64//!
65//! ### Match Details V1
66//!
67//! Function: [`get_match_details_v1`]
68//!
69//! Result Type: [`MatchDetailsV1`]
70//!
71//! ### Match History V1
72//!
73//! Function: [`get_match_history_v1`]
74//!
75//! Result Type: [`MatchHistoryV1`]
76//!
77//! ### MMRV1
78//!
79//! Function: [`get_mmr_details_v1`]
80//!
81//! Result Type: [`MMRDetailsV1`]
82//!
83//! ### Leaderboard V1
84//!
85//! Function: [`get_leaderboard_v1`]
86//!
87//! Result Type: [`LeaderboardV1`]
88//!
89//! ### Content V3
90//!
91//! Function: [`get_content_v3`]
92//!
93//! Result Type: [`ContentV3`]
94//!
95//! ### Store Offers V1
96//!
97//! Function: [`get_store_offers_v1`]
98//!
99//! Result Type: [`StoreOffersV1`]
100//!
101//! ### Store Front V2
102//!
103//! Function: [`get_store_front_v2`]
104//!
105//! Result Type: [`StoreFrontV2`]
106//!
107
108use std::collections::HashMap;
109use std::str::FromStr;
110use std::string::ToString;
111
112use reqwest::{Client, Method};
113use url::Url;
114use uuid::Uuid;
115
116use crate::enums::esport_locales::EsportsLocales;
117use crate::enums::platform::Platform;
118use crate::enums::query_arg::{
119 CompetitiveUpdateQueryArg, LeaderboardQueryArg, MatchHistoryQueryArg,
120};
121use crate::enums::region::Region;
122use crate::errors::response_error::RequestError;
123use crate::response_types::account_aliases_v1::AccountAliasesV1;
124use crate::response_types::competitive_updates_v1::CompetitiveUpdatesV1;
125use crate::response_types::content_v3::ContentV3;
126use crate::response_types::esports_service_leagues::EsportsLeagues;
127use crate::response_types::esports_service_schedule::EsportsSchedule;
128use crate::response_types::esports_service_vods::EsportsVod;
129use crate::response_types::leaderboard_v1::LeaderboardV1;
130use crate::response_types::matchdetails_v1::MatchDetailsV1;
131use crate::response_types::matchhistory_v1::MatchHistoryV1;
132use crate::response_types::mmrdetails_v1::MMRDetailsV1;
133use crate::response_types::store_front_v2::StoreFrontV2;
134use crate::response_types::store_offers_v1::StoreOffersV1;
135use crate::utils::credentials_manager::CredentialsManager;
136use crate::utils::fetch::fetch_endpoint;
137use crate::utils::functions::set_query_args;
138
139pub mod enums;
140pub mod errors;
141pub mod response_types;
142pub mod utils;
143
144const ESPORTS_API_KEY: &str = "0TvQnueqKa5mxJntVWt0w4LpLfEkrV1Ta8rQBb9Z";
145
146pub async fn get_match_history_v1(
147 credentials_manager: &CredentialsManager,
148 http_client: &Client,
149 region: Region,
150 puuid: &Uuid,
151 query_args: HashMap<MatchHistoryQueryArg, String>,
152) -> Result<MatchHistoryV1, RequestError> {
153 //! Get the match history of a player
154 //! # Arguments
155 //! * `credentials_manager` - The credentials manager
156 //! * `region` - The region of the player
157 //! * `puuid` - The puuid of the player
158 //! * `query_args` - The query arguments
159 //! # Example
160 //! ```rust no_run
161 //! let puuid = Uuid::parse_str("ee89b4d9-13d0-5832-8dd7-eb5d8806d918").expect("Invalid UUID");
162 //! let region = Region::EU;
163 //! let queries = HashMap::new();
164 //! let result = valorant_api::get_match_history_v1(credentials_manager, &http_client, region, &puuid, queries).await;
165 //! println!("Result: {:#?}", result);
166 //! ```
167
168 let mut url = Url::from_str(&format!(
169 "https://pd.{}.a.pvp.net/match-history/v1/history/{}",
170 region.to_shard(),
171 puuid
172 ))?;
173 set_query_args(&mut url, query_args.into_iter());
174
175 fetch_endpoint(
176 credentials_manager,
177 http_client,
178 url,
179 Method::GET,
180 "",
181 &HashMap::new(),
182 )
183 .await
184}
185
186pub async fn get_match_details_v1(
187 credentials_manager: &CredentialsManager,
188 http_client: &Client,
189 region: Region,
190 match_id: &Uuid,
191) -> Result<MatchDetailsV1, RequestError> {
192 //! Get the match details of a match
193 //! # Arguments
194 //! * `credentials_manager` - The credentials manager
195 //! * `region` - The region of the match
196 //! * `match_id` - The match id of the match
197 //! # Example
198 //! ```rust no_run
199 //! let match_id = Uuid::parse_str("3100c02b-17d2-4adb-97b5-e45dee67d292").expect("Invalid UUID");
200 //! let region = Region::EU;
201 //! let result = valorant_api::get_match_details_v1(credentials_manager, &http_client, region, &match_id).await;
202 //! println!("Result: {:#?}", result);
203 //! ```
204
205 let url = Url::from_str(&format!(
206 "https://pd.{}.a.pvp.net/match-details/v1/matches/{}",
207 region.to_shard(),
208 match_id
209 ))?;
210
211 fetch_endpoint(
212 credentials_manager,
213 http_client,
214 url,
215 Method::GET,
216 "",
217 &HashMap::new(),
218 )
219 .await
220}
221
222pub async fn get_mmr_details_v1(
223 credentials_manager: &CredentialsManager,
224 http_client: &Client,
225 region: Region,
226 puuid: &Uuid,
227) -> Result<MMRDetailsV1, RequestError> {
228 //! Get the mmr of a player
229 //! # Arguments
230 //! * `credentials_manager` - The credentials manager
231 //! * `region` - The region of the player
232 //! * `puuid` - The puuid of the player
233 //! # Example
234 //! ```rust no_run
235 //! let puuid = Uuid::parse_str("ee89b4d9-13d0-5832-8dd7-eb5d8806d918").expect("Invalid UUID");
236 //! let region = Region::EU;
237 //! let result = valorant_api::get_mmr_details_v1(credentials_manager, &http_client, region, &puuid).await;
238 //! println!("Result: {:#?}", result);
239 //! ```
240
241 let url = Url::from_str(&format!(
242 "https://pd.{}.a.pvp.net/mmr/v1/players/{}",
243 region.to_shard(),
244 puuid
245 ))?;
246
247 fetch_endpoint(
248 credentials_manager,
249 http_client,
250 url,
251 Method::GET,
252 "",
253 &HashMap::new(),
254 )
255 .await
256}
257
258pub async fn get_competitive_updates_v1(
259 credentials_manager: &CredentialsManager,
260 http_client: &Client,
261 region: Region,
262 puuid: &Uuid,
263 query_args: HashMap<CompetitiveUpdateQueryArg, String>,
264) -> Result<CompetitiveUpdatesV1, RequestError> {
265 //! Get the competitve updates of a player
266 //! # Arguments
267 //! * `credentials_manager` - The credentials manager
268 //! * `region` - The region of the player
269 //! * `puuid` - The puuid of the player
270 //! * `query_args` - The query arguments
271 //! # Example
272 //! ```rust no_run
273 //! let puuid = Uuid::parse_str("ee89b4d9-13d0-5832-8dd7-eb5d8806d918").expect("Invalid UUID");
274 //! let region = Region::EU;
275 //! let queries = HashMap::new();
276 //! let result = valorant_api::get_competitve_updates_v1(credentials_manager, &http_client, region, &puuid, queries).await;
277 //! println!("Result: {:#?}", result);
278 //! ```
279
280 let mut url = Url::from_str(&format!(
281 "https://pd.{}.a.pvp.net/mmr/v1/players/{}/competitiveupdates",
282 region.to_shard(),
283 puuid
284 ))?;
285 set_query_args(&mut url, query_args.into_iter());
286
287 fetch_endpoint(
288 credentials_manager,
289 http_client,
290 url,
291 Method::GET,
292 "",
293 &HashMap::new(),
294 )
295 .await
296}
297
298pub async fn get_content_v3(
299 credentials_manager: &CredentialsManager,
300 http_client: &Client,
301 region: Region,
302) -> Result<ContentV3, RequestError> {
303 //! Get the content of the game
304 //! # Arguments
305 //! * `credentials_manager` - The credentials manager
306 //! * `region` - The region of the player
307 //! # Example
308 //! ```rust no_run
309 //! let region = Region::EU;
310 //! let result = valorant_api::get_content_v1(credentials_manager, &http_client, region).await;
311 //! println!("Result: {:#?}", result);
312 //! ```
313
314 let url = Url::from_str(&format!(
315 "https://shared.{}.a.pvp.net/content-service/v3/content",
316 region.to_shard(),
317 ))?;
318
319 fetch_endpoint(
320 credentials_manager,
321 http_client,
322 url,
323 Method::GET,
324 "",
325 &HashMap::new(),
326 )
327 .await
328}
329
330pub async fn get_leaderboard_v1(
331 credentials_manager: &CredentialsManager,
332 http_client: &Client,
333 region: Region,
334 season: &Uuid,
335 query_args: HashMap<LeaderboardQueryArg, String>,
336) -> Result<LeaderboardV1, RequestError> {
337 //! Get the leaderboard of a region
338 //! # Arguments
339 //! * `credentials_manager` - The credentials manager
340 //! * `region` - The region of the leaderboard
341 //! * `season` - The season of the leaderboard
342 //! * `query_args` - The query arguments
343 //! # Errors
344 //! `RequestError` - If the request failed
345 //! # Example
346 //! ```rust no_run
347 //! let season = Uuid::parse_str("34093c29-4306-43de-452f-3f944bde22be").expect("Invalid UUID");
348 //! let region = Region::EU;
349 //! let queries = HashMap::new();
350 //! let result = valorant_api::get_leaderboard_v1(credentials_manager, &http_client, region, &season, queries).await;
351 //! println!("Result: {:#?}", result);
352 //! ```
353
354 let queue = match credentials_manager.platform {
355 Platform::PC => "competitive",
356 Platform::XBOX | Platform::PlayStation => "console_competitive",
357 };
358 let mut url = Url::from_str(&format!(
359 "https://pd.{}.a.pvp.net/mmr/v1/leaderboards/affinity/{}/queue/{}/season/{}",
360 region.to_shard(),
361 region,
362 queue,
363 season
364 ))?;
365 set_query_args(&mut url, query_args.into_iter());
366
367 fetch_endpoint(
368 credentials_manager,
369 http_client,
370 url,
371 Method::GET,
372 "",
373 &HashMap::new(),
374 )
375 .await
376}
377
378pub async fn get_store_offers_v1(
379 credentials_manager: &CredentialsManager,
380 http_client: &Client,
381 region: Region,
382) -> Result<StoreOffersV1, RequestError> {
383 //! Get the store offers of a region
384 //! # Arguments
385 //! * `credentials_manager` - The credentials manager
386 //! * `region` - The region of the leaderboard
387 //! # Errors
388 //! `RequestError` - If the request failed
389 //! # Example
390 //! ```rust no_run
391 //! let season = Uuid::parse_str("34093c29-4306-43de-452f-3f944bde22be").expect("Invalid UUID");
392 //! let region = Region::EU;
393 //! let result = valorant_api::get_store_offers_v1(credentials_manager, &http_client, region).await;
394 //! println!("Result: {:#?}", result);
395 //! ```
396
397 let url = Url::from_str(&format!(
398 "https://pd.{}.a.pvp.net/store/v1/offers/",
399 region.to_shard(),
400 ))?;
401
402 fetch_endpoint(
403 credentials_manager,
404 http_client,
405 url,
406 Method::GET,
407 "",
408 &HashMap::new(),
409 )
410 .await
411}
412
413pub async fn get_store_front_v2(
414 credentials_manager: &CredentialsManager,
415 http_client: &Client,
416 region: Region,
417 puuid: Uuid,
418) -> Result<StoreFrontV2, RequestError> {
419 //! Get the store front of a player
420 //! # Arguments
421 //! * `credentials_manager` - The credentials manager
422 //! * `region` - The region of the leaderboard
423 //! * `puuid` - The puuid of the player
424 //! # Errors
425 //! `RequestError` - If the request failed
426 //! # Example
427 //! ```rust no_run
428 //! let puuid = Uuid::parse_str("34093c29-4306-43de-452f-3f944bde22be").expect("Invalid UUID");
429 //! let region = Region::EU;
430 //! let result = valorant_api::get_store_front_v1(credentials_manager, &http_client, region, puuid).await;
431 //! println!("Result: {:#?}", result);
432 //! ```
433
434 let url = Url::from_str(&format!(
435 "https://pd.{}.a.pvp.net/store/v2/storefront/{}",
436 region.to_shard(),
437 puuid,
438 ))?;
439
440 fetch_endpoint(
441 credentials_manager,
442 http_client,
443 url,
444 Method::GET,
445 "",
446 &HashMap::new(),
447 )
448 .await
449}
450
451pub async fn get_account_aliases(
452 credentials_manager: &CredentialsManager,
453 http_client: &Client,
454 cluster: &str,
455 game_name: Option<&str>,
456 tag_line: Option<&str>,
457) -> Result<AccountAliasesV1, RequestError> {
458 //! Get the account aliases of a player.
459 //! This can be used to search for an account by game name and/or tag_line and get their puuid.
460 //! # Arguments
461 //! * `credentials_manager` - The credentials manager
462 //! * `http_client` - The http client
463 //! * `cluster` - The cluster of the player
464 //! * `game_name` - The game name of the player
465 //! * `tag_line` - The tag line of the player
466 //! # Errors
467 //! `RequestError` - If the request failed
468 //! # Example
469 //! ```rust no_run
470 //! let result = valorant_api::get_account_aliases(credentials_manager, &http_client, "eu", None, None).await;
471 //! println!("Result: {:#?}", result);
472 //! ```
473 let mut url = Url::from_str(&format!(
474 "https://{}.api.account.riotgames.com/aliases/v1/aliases",
475 cluster
476 ))?;
477 if let Some(game_name) = game_name {
478 url.query_pairs_mut().append_pair("gameName", game_name);
479 }
480 if let Some(tag_line) = tag_line {
481 url.query_pairs_mut().append_pair("tagLine", tag_line);
482 }
483
484 fetch_endpoint(
485 credentials_manager,
486 http_client,
487 url,
488 Method::GET,
489 "",
490 &HashMap::new(),
491 )
492 .await
493}
494
495pub async fn get_esports_leagues(
496 credentials_manager: &CredentialsManager,
497 http_client: &Client,
498 locale: EsportsLocales,
499) -> Result<EsportsLeagues, RequestError> {
500 //! Get all active valorant esports leagues.
501 //! # Arguments
502 //! * `credentials_manager` - The credentials manager
503 //! * `http_client` - The http client
504 //! * `locale` - The locale in which the leagues should be returned
505 //! # Errors
506 //! `RequestError` - If the request failed
507 //! # Example
508 //! ```rust no_run
509 //! let result = valorant_api::get_esports_leagues(&credential_manager, &http_client, EsportsLocales::US).await;
510 //! println!("Result: {:#?}", result);
511 //! ```
512 let url = Url::from_str(&format!(
513 "https://esports-api.service.valorantesports.com/persisted/val/getLeagues?hl={}&sport=val",
514 locale
515 ))?;
516 fetch_endpoint(
517 credentials_manager,
518 http_client,
519 url,
520 Method::GET,
521 "",
522 &HashMap::from([("x-api-key".to_string(), ESPORTS_API_KEY.to_string())]),
523 )
524 .await
525}
526
527pub async fn get_esports_schedule(
528 credentials_manager: &CredentialsManager,
529 http_client: &Client,
530 locale: EsportsLocales,
531) -> Result<EsportsSchedule, RequestError> {
532 //! Get the schedule for all professional valorant games.
533 //! # Arguments
534 //! * `credentials_manager` - The credentials manager
535 //! * `http_client` - The http client
536 //! * `locale` - The locale in which the schedules should be returned
537 //! # Errors
538 //! `RequestError` - If the request failed
539 //! # Example
540 //! ```rust no_run
541 //! let result = valorant_api::get_esports_schedule(&credential_manager, &http_client, EsportsLocales::US).await;
542 //! println!("Result: {:#?}", result);
543 //! ```
544 let url = Url::from_str(&format!(
545 "https://esports-api.service.valorantesports.com/persisted/val/getSchedule?hl={}&sport=val",
546 locale
547 ))?;
548
549 fetch_endpoint(
550 credentials_manager,
551 http_client,
552 url,
553 Method::GET,
554 "",
555 &HashMap::from([("x-api-key".to_string(), ESPORTS_API_KEY.to_string())]),
556 )
557 .await
558}
559
560pub async fn get_esports_vods(
561 credentials_manager: &CredentialsManager,
562 http_client: &Client,
563 locale: EsportsLocales,
564) -> Result<EsportsVod, RequestError> {
565 //! Get the vod data for each game.
566 //! # Arguments
567 //! * `credentials_manager` - The credentials manager
568 //! * `http_client` - The http client
569 //! * `locale` - The locale in which the vod data should be returned
570 //! # Errors
571 //! `RequestError` - If the request failed
572 //! # Example
573 //! ```rust no_run
574 //! let result = valorant_api::get_esports_vods(&credential_manager, &http_client, EsportsLocales::US).await;
575 //! println!("Result: {:#?}", result);
576 //! ```
577 let url = Url::from_str(&format!(
578 "https://esports-api.service.valorantesports.com/persisted/val/getVods?hl={}&sport=val",
579 locale
580 ))?;
581
582 fetch_endpoint(
583 credentials_manager,
584 http_client,
585 url,
586 Method::GET,
587 "",
588 &HashMap::from([("x-api-key".to_string(), ESPORTS_API_KEY.to_string())]),
589 )
590 .await
591}